<commit_before>import os
import webbrowser
import svgwrite
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def intensity_2(image):
  arr=np.asarray(image)
  mini=999
  maxi=0
  for i in range(len(arr)):
    for j in range(len(arr[0])):
      maxi=max(arr[i][j],maxi)
      mini=min(arr[i][j],mini)
  level=float(float(maxi-mini)/float(10));
  brr=[[0]*len(arr[0]) for i in range(len(arr))]
  for i in range(10):
    l1=mini+level*i
    l2=l1+level
    for j in range(len(arr)):
      for k in range(len(arr[0])):
        if(arr[j][k]>=l1 and arr[j][k]<=l2):
          brr[j][k]=i
  gray_level=[0]*10
  #print len(arr), len(arr[0]),len(brr),len(brr[0])

  gray_level[0] = 2.5
  gray_level[1] = 2.2
  gray_level[2] = 2
  gray_level[3] = 1.8
  gray_level[4] = 1.6
  gray_level[5]=  1.4
  gray_level[6] = 1.2
  gray_level[7] = 1
  gray_level[8] = 0.8
  gray_level[9] = 0
  #crr=[[0]*(len(arr[0])*3) for i in (range(len(arr))*3)]
  startu=0
  endu=0

  dwg = svgwrite.Drawing('test.svg', profile='full')
  for i in range(len(brr)):
  	for j in range(len(brr[i])):
  		dwg.add(dwg.circle((int((startu+startu+5)/2),int((endu+endu+5)/2)),gray_level[brr[i][j]]))
  		startu=startu+5
  		#print startu,endu
  	endu=endu+5
  	startu=0
  dwg.save()
  browser=webbrowser.get('firefox')
  browser.open_new('file://' + os.path.realpath("test.svg"))

fname = 'test.jpg'
image = Image.open(fname)
image = Image.open(fname).convert('L')
#intensity_1(image,3)
#intensity_1(image,5)
#intensity_1(image,7)
intensity_2(image)<commit_msg>fixed the size of halftone SVG image<commit_after>import os
import webbrowser
import svgwrite
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def intensity_2(image):
  arr=np.asarray(image)
  mini=999
  maxi=0
  for i in range(len(arr)):
    for j in range(len(arr[0])):
      maxi=max(arr[i][j],maxi)
      mini=min(arr[i][j],mini)
  level=float(float(maxi-mini)/float(10));
  brr=[[0]*len(arr[0]) for i in range(len(arr))]
  for i in range(10):
    l1=mini+level*i
    l2=l1+level
    for j in range(len(arr)):
      for k in range(len(arr[0])):
        if(arr[j][k]>=l1 and arr[j][k]<=l2):
          brr[j][k]=i
  gray_level=[0]*10
  #print len(arr), len(arr[0]),len(brr),len(brr[0])

  gray_level[0] = 2.5
  gray_level[1] = 2.2
  gray_level[2] = 2
  gray_level[3] = 1.8
  gray_level[4] = 1.6
  gray_level[5]=  1.4
  gray_level[6] = 1.2
  gray_level[7] = 1
  gray_level[8] = 0.8
  gray_level[9] = 0
  #crr=[[0]*(len(arr[0])*3) for i in (range(len(arr))*3)]
  startu=0
  endu=0

#viewBox=('0 0 3000 3000')
  dwg = svgwrite.Drawing('test.svg', profile='full',size=('70cm', '70cm'))
  for i in range(len(brr)):
  	for j in range(len(brr[i])):
  		dwg.add(dwg.circle((int((startu+startu+5)/2),int((endu+endu+5)/2)),gray_level[brr[i][j]]))
  		startu=startu+5
  		#print startu,endu
  	endu=endu+5
  	startu=0
  dwg.save()
  browser=webbrowser.get('firefox')
  browser.open_new('file://' + os.path.realpath("test.svg"))

fname = 'test.jpg'
image = Image.open(fname)
image = Image.open(fname).convert('L')
#intensity_1(image,3)
#intensity_1(image,5)
#intensity_1(image,7)
intensity_2(image)<|endoftext|>


<commit_before>#
# Copyright (c) 2005 rPath, Inc.
#
# All rights reserved
#
import base64
import os
import stat
import sys
import re
from urllib import quote, unquote

from mod_python import apache

import versions
from web import fields
from web.fields import strFields, intFields, listFields, boolFields

from mint import mint_error
from mint import projects
from mint import shimclient
from mint import users
from mint import userlevels
from mint import mailinglists

from webhandler import WebHandler, normPath
from decorators import requiresAdmin, requiresAuth
from decorators import mailList

class SiteHandler(WebHandler):
    def handle(self, context):
        self.__dict__.update(**context)

        path = normPath(context['cmd'])
        cmd = path.split('/')[1]

        if not cmd:
            return self._frontPage
        try:
            method = self.__getattribute__(cmd)
        except AttributeError:
            return self._404

        if self.auth.stagnant and cmd not in ['editUserSettings','confirm','logout']:
            return self.confirmEmail
        if not callable(method):
            method = self._404
        return method

    def _frontPage(self, auth):
        news = self.client.getNews()
        self._write("frontPage", news = news, newsLink = self.client.getNewsLink())
        return apache.OK

    def register(self, auth):
        self._write("register", errors=[], kwargs={})
        return apache.OK

    @strFields(username = '', email = '',
               password = '', password2 = '',
               fullName = '', displayEmail = '',
               blurb = '', tos='', privacy='')
    def processRegister(self, auth, username,
                        fullName, email, password,
                        password2, displayEmail,
                        blurb, tos, privacy):
        errors = []
        if not username:
            errors.append("You must supply a username.")
        if not email:
            errors.append("You must supply a valid e-mail address.  This will be used to confirm your account.")
        if not password or not password2:
            errors.append("Password field left blank.")
        if password != password2:
            errors.append("Passwords do not match.")
        if len(password) < 6:
            errors.append("Password must be 6 characters or longer.")
        if not tos:
            errors.append("You must accept the Terms of Service to create an account")
        if not privacy:
            errors.append("You must accept the Privacy Policy to create an account")
        if not errors:
            try:
                self.client.registerNewUser(username, password, fullName, email,
                            displayEmail, blurb)
            except users.UserAlreadyExists:
                errors.append("An account with that username already exists.")
            except users.GroupAlreadyExists:
                errors.append("An account with that username already exists.")
            except users.MailError,e:
                errors.append(e.context);
        if not errors:
            self._write("register_conf", email = email)
        else:
            kwargs = {'username': username,
                      'email': email,
                      'fullName': fullName,
                      'displayEmail': displayEmail,
                      'blurb': blurb,
                      'tos': tos,
                      'privacy': privacy}
            self._write("register", errors=errors, kwargs = kwargs)
        return apache.OK

    def confirmEmail(self, auth, **kwargs):
        self._write("confirmEmail", email=auth.email)
        return apache.OK

    @strFields(page = None)
    def legal(self, auth, page):
        if page not in ["tos", "privacy"]:
            return apache.HTTP_NOT_FOUND

        self._write(page)
        return apache.OK

    @strFields(message = "")
    def login(self, auth, message):
        self.toUrl = "/"
        self._write("login", message = message)
        return apache.OK

    def logout(self, auth):
        self._clearAuth()
        return self._redirect("/")

    def _resetPassword(self, username):
        userId = self.client.getUserIdByName(username)
        user = self.client.getUser(userId)
        self._resetPasswordById(userId)
        self._write("forgotPassword", email = user.getEmail())
        return apache.OK

    @strFields(username = None, password = '', submit = None, to = '/')
    def processLogin(self, auth, username, password, submit, to):
        if submit == "Log In":
            authToken = (username, password)
            client = shimclient.ShimMintClient(self.cfg, authToken)
            auth = client.checkAuth()

            if not auth.authorized:
                raise mint_error.InvalidLogin
            else:
                client.updateAccessedTime(auth.userId)
                self.session['authToken'] = authToken

                # mod_python's cookie classes don't handle 301 redirects because
                # Cookie.add_cookie only adds cookie headers to req.headers_out,
                # not req_error_headers_out, which is used for redirects,
                # so we have to manually add the cookie to the right headers
                # table.
                c = self.session.make_cookie()
                self.req.err_headers_out.add('Set-Cookie', str(c))
                self.req.err_headers_out.add('Cache-Control', 'no-cache="set-cookie"')

                self.session.save()
                return self._redirect(unquote(to))

        elif submit == "Forgot Password":
            return self._resetPassword(username)
        else:
            return apache.HTTP_NOT_FOUND

    @strFields(id = None)
    def confirm(self, auth, id):
        try:
            self.client.confirmUser(id)
        except users.ConfirmError:
            self._write("error", shortError = "Confirm Failed",
                error = "Sorry, an error has occurred while confirming your registration.")
        except users.AlreadyConfirmed:
            self._write("error", shortError = "Already Confirmed",
                error = "Your account has already been confirmed.")
        else:
            if auth.authorized:
                return self._redirect("/")
            else:
                self._write("register_active")
        return apache.OK

    @intFields(sortOrder = 0, limit = 10, offset = 0)
    def projects(self, auth, sortOrder, limit, offset, submit = 0):
        results, count = self.client.getProjects(sortOrder, limit, offset)
        self._write("projects", sortOrder=sortOrder, limit=limit, offset=offset, results=results, count=count)
        return apache.OK

    @requiresAdmin
    @intFields(sortOrder = 0, limit = 10, offset = 0)
    def users(self, auth, sortOrder, limit, offset, submit = 0):
        results, count = self.client.getUsers(sortOrder, limit, offset)
        self._write("users", sortOrder=sortOrder, limit=limit, offset=offset, results=results, count=count)
        return apache.OK

    @requiresAuth
    def userSettings(self, auth):
        self._write("userSettings")
        return apache.OK

    @strFields(email = "", displayEmail = "",
               password1 = "", password2 = "",
               fullName = "", blurb = "")
    @requiresAuth
    def editUserSettings(self, auth, email, displayEmail, fullName,
                         password1, password2, blurb):
        if email != auth.email:
            self.user.validateNewEmail(email)
            self.user.setEmail(email)
            self._clearAuth()
            self._write("register_reconf", email = email)
            return apache.OK

        if displayEmail != auth.displayEmail:
            self.user.setDisplayEmail(displayEmail)
        if blurb != auth.blurb:
            self.user.setBlurb(blurb)
        if fullName != auth.fullName:
            self.user.setFullName(fullName)

        if password1 and password2:
            if password1 != password2:
                self._write("error", shortError = "Registration Error",
                            error = "Passwords do not match.")
            elif len(password1) < 6:
                self._write("error", shortError = "Registration Error",
                            error = "Password must be 6 characters or longer.")
            else:
                self.user.setPassword(password1)
                return self._redirect("logout")

        return self._redirect("/")

    @requiresAuth
    @listFields(str, projects=[])
    @strFields(keydata = '')
    def uploadKey(self, auth, projects, keydata):
        if self.projectList:
            self._write("uploadKey", errors=[], kwargs={})
        else:
            self._write("error", shortError="Not a project member", error="You may not upload a key as you are not a member of any projects.  Create a project, or ask a project owner to add you to their project and then come back")
        return apache.OK

    @requiresAuth
    @listFields(str, projects=None)
    @strFields(keydata=None)
    def processKey(self, auth, projects, keydata):
        for project, level in self.projectList:
            if project.getHostname() in projects:
                try:
                    project.addUserKey(auth.username, keydata)
                except Exception, e:
                    self._write("uploadKey", errors = ['Error uploading key: %s' % str(e)],
                            kwargs={'projects': projects, 'keydata': keydata})
                    return apache.OK
        return self._redirect("/")

    @requiresAuth
    def newProject(self, auth):
        self._write("newProject", errors=[], kwargs={})
        return apache.OK

    @mailList
    def _createProjectLists(self, mlists, auth, projectName, optlists = []):
        lists = mailinglists.GetLists(projectName, optlists)
        lists.update(mailinglists.GetLists(projectName, mailinglists.defaultlists))
        success = True
        error = False
        for name, values in lists.items():
            success = mlists.add_list(self.cfg.MailListPass, name, '', values['description'], auth.email, True, values['moderate'])
            if not success: error = False
        return not error

    @strFields(title = '', hostname = '', projecturl = '', blurb = '')
    @listFields(int, optlists = [])
    @requiresAuth
    def createProject(self, auth, title, hostname, projecturl, blurb, optlists):
        hostname = hostname.lower()
        errors = []
        if not title:
            error.append("You must supply a project title")
        if not hostname:
            error.append("You must supply a project hostname")
        if not errors:
            try:
                #attempt to create the project
                projectId = self.client.newProject(title, hostname,
                                self.cfg.domainName, projecturl, blurb)
                #Now create the mailing lists
                if self.cfg.EnableMailLists and not errors:
                    if not self._createProjectLists(auth=auth,
                                                    projectName=hostname,
                                                    optlists=optlists):
                        raise mailinglists.MailingListException("Could not create the mailing lists, check the mailing list page to set up your desired lists.")
            except mailinglists.MailingListException:
                raise
            except projects.DuplicateHostname, e:
                errors.append(str(e))
            except projects.DuplicateName, e:
                errors.append(str(e))
            except mint_error.MintError, e:
                errors.append(str(e))
        if not errors:
            return self._redirect("http://%s/project/%s/" % (self.siteHost, hostname))
        else:
            kwargs = {'title': title, 'hostname': hostname, 'projecturl': projecturl, 'blurb': blurb, 'optlists': optlists}
            self._write("newProject", errors=errors, kwargs=kwargs)
            return apache.OK

    @intFields(userId = None, projectId = None, level = None)
    def addMemberById(self, auth, userId, projectId, level):
        project = self.client.getProject(projectId)

        if project.getUserLevel(auth.userId) != userlevels.OWNER:
            raise mint_error.PermissionDenied

        project.addMemberById(userId, level)
        return self._redirect("http://%s" % project.getFQDN())

    @intFields(id = None)
    def userInfo(self, auth, id):
        user = self.client.getUser(id)
        self._write("userInfo", user = user,
            userProjects = self.client.getProjectsByMember(id))
        return apache.OK

    @strFields(search = "", type = None)
    @intFields(limit = 10, offset = 0, modified = 0)
    def search(self, auth, type, search, modified, limit, offset):
        if type == "Projects" and auth.admin:
            return self._projectSearch(search, modified, limit, offset)
        elif type == "Users" and auth.admin:
            return self._userSearch(auth, search, limit, offset)
        elif type == "Packages":
            return self._packageSearch(search, limit, offset)
        else:
            self._write("error", shortError = "Invalid Search Type",
                error = "Invalid search type specified.")
            return apache.OK

    def _userSearch(self, auth, terms, limit, offset):
        results, count = self.client.getUserSearchResults(terms, limit, offset)
        self._write("searchResults", searchType = "Users", terms = terms, results = results,
                                     count = count, limit = limit, offset = offset,
                                     modified = 0)
        return apache.OK

    def _packageSearch(self, terms, limit, offset):
        results, count = self.client.getPackageSearchResults(terms, limit, offset)

        searchResults = []
        for x in results:
            if x[2]:
                p = self.client.getProject(x[2])
                name = p.getName()
                host = p.getFQDN()
            else:
                version = versions.VersionFromString(x[1])
                name = version.branch().label().host()
                host = name
            searchResults.append( (x[0], x[1], x[2], x[3]) )

        self._write("searchResults", searchType = "Packages", terms = terms, results = searchResults,
                                     count = count, limit = limit, offset = offset,
                                     modified = 0)
        return apache.OK

    def _projectSearch(self, terms, modified, limit, offset):
        results, count = self.client.getProjectSearchResults(terms, modified, limit, offset)
        self._write("searchResults", searchType = "Projects", terms = terms, results = results,
                                     count = count, limit = limit, offset = offset,
                                     modified = modified)
        return apache.OK

    @intFields(fileId = None)
    def downloadImage(self, auth, fileId):
        filename = self.client.getFilename(fileId)

        try:
            size = os.stat(filename)[stat.ST_SIZE]

            self.req.content_type = "application/octet-stream"
            self.req.headers_out["Content-Disposition"] = "attachment; filename=%s;" %\
                os.path.basename(filename)
            self.req.headers_out["Content-Length"] = str(size)
            self.req.sendfile(filename)
        except OSError, e:
            self._write("error", shortError = "File error",
                        error = "An error has occurred opening the image file: %s" % e)
        return apache.OK

    @requiresAuth
    @boolFields(confirmed = False)
    def cancelAccount(self, auth, confirmed):
        if confirmed:
            #do the actual deletion
            self.user.cancelUserAccount()
            self._clearAuth()
            return self._redirect("/")
        else:
            self._write("confirm", message = "Are you sure you want to delete your account?",
                yesLink = "cancelAccount?confirmed=1",
                noLink = "/")
        return apache.OK
<commit_msg>fix package search<commit_after>#
# Copyright (c) 2005 rPath, Inc.
#
# All rights reserved
#
import base64
import os
import stat
import sys
import re
from urllib import quote, unquote

from mod_python import apache

import versions
from web import fields
from web.fields import strFields, intFields, listFields, boolFields

from mint import mint_error
from mint import projects
from mint import shimclient
from mint import users
from mint import userlevels
from mint import mailinglists

from webhandler import WebHandler, normPath
from decorators import requiresAdmin, requiresAuth
from decorators import mailList

class SiteHandler(WebHandler):
    def handle(self, context):
        self.__dict__.update(**context)

        path = normPath(context['cmd'])
        cmd = path.split('/')[1]

        if not cmd:
            return self._frontPage
        try:
            method = self.__getattribute__(cmd)
        except AttributeError:
            return self._404

        if self.auth.stagnant and cmd not in ['editUserSettings','confirm','logout']:
            return self.confirmEmail
        if not callable(method):
            method = self._404
        return method

    def _frontPage(self, auth):
        news = self.client.getNews()
        self._write("frontPage", news = news, newsLink = self.client.getNewsLink())
        return apache.OK

    def register(self, auth):
        self._write("register", errors=[], kwargs={})
        return apache.OK

    @strFields(username = '', email = '',
               password = '', password2 = '',
               fullName = '', displayEmail = '',
               blurb = '', tos='', privacy='')
    def processRegister(self, auth, username,
                        fullName, email, password,
                        password2, displayEmail,
                        blurb, tos, privacy):
        errors = []
        if not username:
            errors.append("You must supply a username.")
        if not email:
            errors.append("You must supply a valid e-mail address.  This will be used to confirm your account.")
        if not password or not password2:
            errors.append("Password field left blank.")
        if password != password2:
            errors.append("Passwords do not match.")
        if len(password) < 6:
            errors.append("Password must be 6 characters or longer.")
        if not tos:
            errors.append("You must accept the Terms of Service to create an account")
        if not privacy:
            errors.append("You must accept the Privacy Policy to create an account")
        if not errors:
            try:
                self.client.registerNewUser(username, password, fullName, email,
                            displayEmail, blurb)
            except users.UserAlreadyExists:
                errors.append("An account with that username already exists.")
            except users.GroupAlreadyExists:
                errors.append("An account with that username already exists.")
            except users.MailError,e:
                errors.append(e.context);
        if not errors:
            self._write("register_conf", email = email)
        else:
            kwargs = {'username': username,
                      'email': email,
                      'fullName': fullName,
                      'displayEmail': displayEmail,
                      'blurb': blurb,
                      'tos': tos,
                      'privacy': privacy}
            self._write("register", errors=errors, kwargs = kwargs)
        return apache.OK

    def confirmEmail(self, auth, **kwargs):
        self._write("confirmEmail", email=auth.email)
        return apache.OK

    @strFields(page = None)
    def legal(self, auth, page):
        if page not in ["tos", "privacy"]:
            return apache.HTTP_NOT_FOUND

        self._write(page)
        return apache.OK

    @strFields(message = "")
    def login(self, auth, message):
        self.toUrl = "/"
        self._write("login", message = message)
        return apache.OK

    def logout(self, auth):
        self._clearAuth()
        return self._redirect("/")

    def _resetPassword(self, username):
        userId = self.client.getUserIdByName(username)
        user = self.client.getUser(userId)
        self._resetPasswordById(userId)
        self._write("forgotPassword", email = user.getEmail())
        return apache.OK

    @strFields(username = None, password = '', submit = None, to = '/')
    def processLogin(self, auth, username, password, submit, to):
        if submit == "Log In":
            authToken = (username, password)
            client = shimclient.ShimMintClient(self.cfg, authToken)
            auth = client.checkAuth()

            if not auth.authorized:
                raise mint_error.InvalidLogin
            else:
                client.updateAccessedTime(auth.userId)
                self.session['authToken'] = authToken

                # mod_python's cookie classes don't handle 301 redirects because
                # Cookie.add_cookie only adds cookie headers to req.headers_out,
                # not req_error_headers_out, which is used for redirects,
                # so we have to manually add the cookie to the right headers
                # table.
                c = self.session.make_cookie()
                self.req.err_headers_out.add('Set-Cookie', str(c))
                self.req.err_headers_out.add('Cache-Control', 'no-cache="set-cookie"')

                self.session.save()
                return self._redirect(unquote(to))

        elif submit == "Forgot Password":
            return self._resetPassword(username)
        else:
            return apache.HTTP_NOT_FOUND

    @strFields(id = None)
    def confirm(self, auth, id):
        try:
            self.client.confirmUser(id)
        except users.ConfirmError:
            self._write("error", shortError = "Confirm Failed",
                error = "Sorry, an error has occurred while confirming your registration.")
        except users.AlreadyConfirmed:
            self._write("error", shortError = "Already Confirmed",
                error = "Your account has already been confirmed.")
        else:
            if auth.authorized:
                return self._redirect("/")
            else:
                self._write("register_active")
        return apache.OK

    @intFields(sortOrder = 0, limit = 10, offset = 0)
    def projects(self, auth, sortOrder, limit, offset, submit = 0):
        results, count = self.client.getProjects(sortOrder, limit, offset)
        self._write("projects", sortOrder=sortOrder, limit=limit, offset=offset, results=results, count=count)
        return apache.OK

    @requiresAdmin
    @intFields(sortOrder = 0, limit = 10, offset = 0)
    def users(self, auth, sortOrder, limit, offset, submit = 0):
        results, count = self.client.getUsers(sortOrder, limit, offset)
        self._write("users", sortOrder=sortOrder, limit=limit, offset=offset, results=results, count=count)
        return apache.OK

    @requiresAuth
    def userSettings(self, auth):
        self._write("userSettings")
        return apache.OK

    @strFields(email = "", displayEmail = "",
               password1 = "", password2 = "",
               fullName = "", blurb = "")
    @requiresAuth
    def editUserSettings(self, auth, email, displayEmail, fullName,
                         password1, password2, blurb):
        if email != auth.email:
            self.user.validateNewEmail(email)
            self.user.setEmail(email)
            self._clearAuth()
            self._write("register_reconf", email = email)
            return apache.OK

        if displayEmail != auth.displayEmail:
            self.user.setDisplayEmail(displayEmail)
        if blurb != auth.blurb:
            self.user.setBlurb(blurb)
        if fullName != auth.fullName:
            self.user.setFullName(fullName)

        if password1 and password2:
            if password1 != password2:
                self._write("error", shortError = "Registration Error",
                            error = "Passwords do not match.")
            elif len(password1) < 6:
                self._write("error", shortError = "Registration Error",
                            error = "Password must be 6 characters or longer.")
            else:
                self.user.setPassword(password1)
                return self._redirect("logout")

        return self._redirect("/")

    @requiresAuth
    @listFields(str, projects=[])
    @strFields(keydata = '')
    def uploadKey(self, auth, projects, keydata):
        if self.projectList:
            self._write("uploadKey", errors=[], kwargs={})
        else:
            self._write("error", shortError="Not a project member", error="You may not upload a key as you are not a member of any projects.  Create a project, or ask a project owner to add you to their project and then come back")
        return apache.OK

    @requiresAuth
    @listFields(str, projects=None)
    @strFields(keydata=None)
    def processKey(self, auth, projects, keydata):
        for project, level in self.projectList:
            if project.getHostname() in projects:
                try:
                    project.addUserKey(auth.username, keydata)
                except Exception, e:
                    self._write("uploadKey", errors = ['Error uploading key: %s' % str(e)],
                            kwargs={'projects': projects, 'keydata': keydata})
                    return apache.OK
        return self._redirect("/")

    @requiresAuth
    def newProject(self, auth):
        self._write("newProject", errors=[], kwargs={})
        return apache.OK

    @mailList
    def _createProjectLists(self, mlists, auth, projectName, optlists = []):
        lists = mailinglists.GetLists(projectName, optlists)
        lists.update(mailinglists.GetLists(projectName, mailinglists.defaultlists))
        success = True
        error = False
        for name, values in lists.items():
            success = mlists.add_list(self.cfg.MailListPass, name, '', values['description'], auth.email, True, values['moderate'])
            if not success: error = False
        return not error

    @strFields(title = '', hostname = '', projecturl = '', blurb = '')
    @listFields(int, optlists = [])
    @requiresAuth
    def createProject(self, auth, title, hostname, projecturl, blurb, optlists):
        hostname = hostname.lower()
        errors = []
        if not title:
            error.append("You must supply a project title")
        if not hostname:
            error.append("You must supply a project hostname")
        if not errors:
            try:
                #attempt to create the project
                projectId = self.client.newProject(title, hostname,
                                self.cfg.domainName, projecturl, blurb)
                #Now create the mailing lists
                if self.cfg.EnableMailLists and not errors:
                    if not self._createProjectLists(auth=auth,
                                                    projectName=hostname,
                                                    optlists=optlists):
                        raise mailinglists.MailingListException("Could not create the mailing lists, check the mailing list page to set up your desired lists.")
            except mailinglists.MailingListException:
                raise
            except projects.DuplicateHostname, e:
                errors.append(str(e))
            except projects.DuplicateName, e:
                errors.append(str(e))
            except mint_error.MintError, e:
                errors.append(str(e))
        if not errors:
            return self._redirect("http://%s/project/%s/" % (self.siteHost, hostname))
        else:
            kwargs = {'title': title, 'hostname': hostname, 'projecturl': projecturl, 'blurb': blurb, 'optlists': optlists}
            self._write("newProject", errors=errors, kwargs=kwargs)
            return apache.OK

    @intFields(userId = None, projectId = None, level = None)
    def addMemberById(self, auth, userId, projectId, level):
        project = self.client.getProject(projectId)

        if project.getUserLevel(auth.userId) != userlevels.OWNER:
            raise mint_error.PermissionDenied

        project.addMemberById(userId, level)
        return self._redirect("http://%s" % project.getFQDN())

    @intFields(id = None)
    def userInfo(self, auth, id):
        user = self.client.getUser(id)
        self._write("userInfo", user = user,
            userProjects = self.client.getProjectsByMember(id))
        return apache.OK

    @strFields(search = "", type = None)
    @intFields(limit = 10, offset = 0, modified = 0)
    def search(self, auth, type, search, modified, limit, offset):
        if type == "Projects" and auth.admin:
            return self._projectSearch(search, modified, limit, offset)
        elif type == "Users" and auth.admin:
            return self._userSearch(auth, search, limit, offset)
        elif type == "Packages":
            return self._packageSearch(search, limit, offset)
        else:
            self._write("error", shortError = "Invalid Search Type",
                error = "Invalid search type specified.")
            return apache.OK

    def _userSearch(self, auth, terms, limit, offset):
        results, count = self.client.getUserSearchResults(terms, limit, offset)
        self._write("searchResults", searchType = "Users", terms = terms, results = results,
                                     count = count, limit = limit, offset = offset,
                                     modified = 0)
        return apache.OK

    def _packageSearch(self, terms, limit, offset):
        results, count = self.client.getPackageSearchResults(terms, limit, offset)

        searchResults = []
        for x in results:
            if x[2]:
                p = self.client.getProject(x[2])
                name = p.getName()
                host = p.getFQDN()
            else:
                version = versions.VersionFromString(x[1])
                name = version.branch().label().getHost()
                host = name
            searchResults.append( (x[0], x[1], host, name) )

        self._write("searchResults", searchType = "Packages", terms = terms, results = searchResults,
                                     count = count, limit = limit, offset = offset,
                                     modified = 0)
        return apache.OK

    def _projectSearch(self, terms, modified, limit, offset):
        results, count = self.client.getProjectSearchResults(terms, modified, limit, offset)
        self._write("searchResults", searchType = "Projects", terms = terms, results = results,
                                     count = count, limit = limit, offset = offset,
                                     modified = modified)
        return apache.OK

    @intFields(fileId = None)
    def downloadImage(self, auth, fileId):
        filename = self.client.getFilename(fileId)

        try:
            size = os.stat(filename)[stat.ST_SIZE]

            self.req.content_type = "application/octet-stream"
            self.req.headers_out["Content-Disposition"] = "attachment; filename=%s;" %\
                os.path.basename(filename)
            self.req.headers_out["Content-Length"] = str(size)
            self.req.sendfile(filename)
        except OSError, e:
            self._write("error", shortError = "File error",
                        error = "An error has occurred opening the image file: %s" % e)
        return apache.OK

    @requiresAuth
    @boolFields(confirmed = False)
    def cancelAccount(self, auth, confirmed):
        if confirmed:
            #do the actual deletion
            self.user.cancelUserAccount()
            self._clearAuth()
            return self._redirect("/")
        else:
            self._write("confirm", message = "Are you sure you want to delete your account?",
                yesLink = "cancelAccount?confirmed=1",
                noLink = "/")
        return apache.OK
<|endoftext|>


<commit_before>from __future__ import with_statement

import os
import json
from sys import exit, argv
import putiopy
import pwd
import time
import requests
from stat import S_IFDIR, S_IFLNK, S_IFREG
from fuse import FUSE, FuseOSError, Operations
import threading
import inotify.adapters
import tempfile
import urllib3

urllib3.disable_warnings()

foldersIds = {}
downloaders = {}

tmp_path = os.path.join(tempfile.gettempdir(), 'putio')
config_file = os.path.join(os.path.expanduser('~'), '.putio-config')
config = {}

class PutioMounter(Operations):
    def __init__(self):
        global config

        self.putio = putiopy.Client(config['token'])
        self.config = config

    def _set_files(self, folder, files):
        for file in files:
            self._add_file(os.path.join(folder, file.name), file)

    def _add_file(self, fullFileName, file):
        foldersIds[fullFileName.replace(os.path.sep + os.path.sep, os.path.sep).encode('utf-8')] = file

    def _get_id(self, path):
        if path == os.path.sep:
            return 0

        return self._get_file(path).id

    def _get_parent_path(self, path):
        return os.path.split(path)[0]

    def _get_file(self, path):
        path = self._full_path(path)
        try:
            return foldersIds[self._full_path(path)]
        except:
            self.readdir(self._get_parent_path(path), False)
            return foldersIds[self._full_path(path)]

    def _full_path(self, partial):
        return partial.encode('utf-8')

    # Filesystem methods
    # ==================

    def access(self, path, mode):
        full_path = self._full_path(path)

    def chmod(self, path, mode):
        full_path = self._full_path(path)

    def chown(self, path, uid, gid):
        full_path = self._full_path(path)

    def getattr(self, path, fh=None):
        uid = pwd.getpwuid(os.getuid()).pw_uid
        gid = pwd.getpwuid(os.getuid()).pw_gid
        self.now = int(time.time())
        parentPath = self._get_parent_path(path)

        if path == os.path.sep:
            return dict(
                 st_mode=S_IFDIR | 0755,
                 st_size=4096,
                 st_ctime=self.now,
                 st_mtime=self.now,
                 st_uid= os.getuid(),
                 st_gid=os.getuid(),
                 st_atime=0,
                 st_nlink=1
             )
        try:
            file = self._get_file(path)
        except:
            st = os.lstat('a-fake-file-which-not-exists')
            return dict((key, getattr(st, key)) for key in ('st_atime', 'st_ctime',
                     'st_gid', 'st_mode', 'st_mtime', 'st_nlink', 'st_size', 'st_uid'))
        try:
            ctime = time.mktime(file.created_at.timetuple())
        except:
            ctime = self.now

        if isinstance(file, self.putio.Subtitle):
            filepath = file.download('/tmp')
            return dict(
                 st_mode=S_IFREG | 0755,
                 st_size=os.path.getsize(filepath),
                 st_ctime=ctime,
                 st_mtime=ctime,
                 st_atime=0,
                 st_uid=os.getuid(),
                 st_gid=os.getuid(),
                 st_nlink=1
             )
        if file.content_type == 'application/x-directory':
           return dict(
                st_mode=S_IFDIR | 0755,
                st_size=4096,
                st_ctime=ctime,
                st_mtime=ctime,
                st_atime=0,
                st_uid=os.getuid(),
                st_gid=os.getuid(),
                st_nlink=1
            )

        filename, file_extension = os.path.splitext(path)
        filename, origin_file_extension = os.path.splitext(file.name)
        if self.config['use_mp4'] and origin_file_extension != '.mp4' and file_extension == '.mp4':
            size = file.get_mp4_size()
        else:
            size = file.size

        return dict(
            st_mode=S_IFREG | 0755,
            st_size=size,
            st_ctime=ctime,
            st_mtime=ctime,
            st_uid= os.getuid(),
            st_gid=os.getuid(),
            st_atime=0,
            st_nlink=1
        )

    def readdir(self, path, fh):
        full_path = self._full_path(path)
        dirents = ['.', '..']
        if full_path != os.path.sep:
            file = self._get_file(full_path)
            files = file.dir()
        else:
            files = self.putio.File.list();

        for file in files:
            filename = file.name
            dirents.append(filename)
            self._add_file(os.path.join(full_path, filename), file)
            file_name, file_extension = os.path.splitext(filename)

            if file.content_type[:6] == 'video/':
                if self.config['use_subtitles']:
                    subtitles = file.get_subtitles()
                    for subtitle in subtitles:
                        filename_subtitle = subtitle.name
                        self._add_file(os.path.join(full_path, filename_subtitle), subtitle)
                        dirents.append(filename_subtitle)
                if self.config['use_mp4'] and file_extension != '.mp4' and file.is_mp4_available:
                    filename_mp4 = os.path.splitext(filename)[0]+'.mp4'
                    self._add_file(os.path.join(full_path, filename_mp4), file)
                    dirents.append(filename_mp4)
                elif self.config['use_mp4'] and file.content_type != 'video/mp4' and not file.is_mp4_available:
                    file.ask_for_mp4()

        return dirents

    def mkdir(self, path, mode):
        pathInfos = os.path.split(path)
        parentPath = pathInfos[0]
        if (parentPath != os.path.sep):
            parentId = self._get_file(parentPath).id
        else:
            parentId = 0

        self.putio.File.create_folder(pathInfos[1], parentId)

    def statfs(self, path):
        return dict(
                  bsize= 1000000,
                  frsize= 1000000,
                  blocks= 1000000,
                  bfree= 1000000,
                  bavail= 1000000,
                  files= 1000000,
                  ffree= 1000000,
                  favail= 1000000,
                  fsid= 1000000,
                  flag= 1000000,
                  namemax= 1000000
               )
    def unlink(self, path):
        file = self._get_file(path);
        return file.delete()

    def rmdir(self, path):
        file = self._get_file(path);
        file.delete()

    def rename(self, old, new):
        file = self._get_file(old)
        pathInfos = os.path.split(path)
        return file.rename(pathInfos[1])

    # File methods
    # ============

    def open(self, path, flags):
        return True

    def create(self, path, mode, fi=None):
        full_path = self._full_path(path)
        return os.open(full_path, os.O_WRONLY | os.O_CREAT, mode)

    def read(self, path, length, offset, fh):
        try:
            fileUrl = links[path]
        except:
            file = self._get_file(path)
            if isinstance(file, self.putio.Subtitle):
                filepath = file.download('/tmp')
                with open(filepath, 'r') as fp:
                    fp.seek(offset)
                    return fp.read(length)

            filename, file_extension = os.path.splitext(path)
            filename, original_file_extension = os.path.splitext(file.name)
            if self.config['use_mp4'] and original_file_extension != '.mp4' and file_extension == '.mp4':
                fileUrl = file.get_stream_link(prefer_mp4=True)
            else:
                fileUrl = file.get_stream_link(prefer_mp4=False)
        try:
            downloader = downloaders[path]
        except:
            downloader = Downloader(fileUrl, file.size, file.id)
            downloaders[path] = downloader

        return downloader.read(offset, length, fileUrl, path)

class Downloader:
    packetSize = 1024 * 2048

    def __init__(self, fileUrl, fileSize, fileId):
        self.packets = []

        self.url = fileUrl
        self.size = fileSize
        self.fileId = fileId

    def _create_packet(self, packet, url):
        if os.path.exists(packet.file):
            return packet

        headers = {"Range": 'bytes=%s-%s' % (str(packet.start), str(packet.end - 1))}
        req = requests.get(url, headers=headers, stream=True)

        with open(packet.file, 'w') as fp:
            for chunk in req.iter_content(chunk_size=512):
                if chunk:
                    fp.write(chunk)
                    fp.flush()

                if os.path.getsize(packet.file) >= self.packetSize or fp.tell()  >= self.packetSize:
                    return packet

        return packet

    def _get_packet(self, offset, length, url, path):
        for packet in self.packets:
            if packet.start <= offset and packet.end >= offset + length:
                return packet

        packet = type('lamdbaobject', (object,), {})()
        packet.start = 0
        packet.path = path
        packet.end = self.packetSize
        packet.id = 1

        while packet.end < offset + length:
            packet.start += self.packetSize
            packet.end = packet.start + self.packetSize
            packet.id += 1

        if packet.end > self.size:
            packet.end = self.size

        filename, file_extension = os.path.splitext(path)
        packet.file = os.path.join(tmp_path, '%s-%s-%s' % (str(self.fileId), str(packet.start), str(file_extension)))
        if not os.path.exists(packet.file):
            clean_old_files()
            thr = threading.Thread(target=self._create_packet, args=(), kwargs={"packet": packet, "url": url})
            thr.start()

        return packet

    def read(self, offset, length, url, path):
        if offset + length > self.size:
            length = self.size - offset

        packet = self._get_packet(offset, length, url, path)

        if not os.path.exists(packet.file) or os.path.getsize(packet.file) < offset - packet.start + length or packet.end < offset + length or offset - packet.start < 0:
            headers = {"Range": 'bytes=%s-%s' % (str(offset), str(offset + length - 1))}
            return requests.get(url, headers=headers).content

        fp = open(packet.file, 'r')
        fp.seek(offset - packet.start)
        data = fp.read(length)
        fp.close()

        if packet.end < self.size and os.path.getsize(packet.file) >= self.packetSize:
            nextPacket = self._get_packet(packet.end + 1, 2, url, path)

        return data

def clean_old_files() :
    now = time.time()
    for f in os.listdir(tmp_path):
        f = os.path.join(tmp_path, f)
        if os.stat(f).st_atime < now - 60 * 60 and os.path.isfile(f):
            os.remove(f)

def main(mount_point):
    mount(mount_point)

def mount(new_mount_point):
    global mount_point
    global config

    mount_point = new_mount_point
    if not os.path.exists(tmp_path):
        os.makedirs(tmp_path)

    if not os.path.exists(config_file):
        defaultConfig = {
            "token": "YOUR_TOKEN_HERE",
            "use_mp4": False,
            "use_subtitles": False
        }

        with open(config_file, 'w') as f:
            f.write(json.dumps(defaultConfig))

    with open(config_file, 'r') as f:
        config = json.loads(f.read())

    if config['token'] is None or config['token'] == 'YOUR_TOKEN_HERE':
        print "Please put your token in %s file." % config_file
        exit()

    FUSE(PutioMounter(), mount_point, nothreads=False, foreground=False,**{'allow_other': True})
    i = inotify.adapters.Inotify()
    i.add_watch(mount_point)

def get_mount_point():
    global mount_point

    return mount_point

def set_config(paramKey, paramValue):
    global config
    global config_file
    config['paramKey'] = paramValue
    with open(config_file, 'w'):
        f.write(json.dumps(config))

def set_config_file(custom_credentials_path):
    global config_file
    config_file = custom_credentials_path

def set_tmp_path(custom_tmp_path):
    global tmp_path
    tmp_path = custom_tmp_path

if __name__ == '__main__':
    main(sys.argv[1])
<commit_msg>fix mp4 size<commit_after>from __future__ import with_statement

import os
import json
from sys import exit, argv
import putiopy
import pwd
import time
import requests
from stat import S_IFDIR, S_IFLNK, S_IFREG
from fuse import FUSE, FuseOSError, Operations
import threading
import inotify.adapters
import tempfile
import urllib3

urllib3.disable_warnings()

foldersIds = {}
downloaders = {}

tmp_path = os.path.join(tempfile.gettempdir(), 'putio')
config_file = os.path.join(os.path.expanduser('~'), '.putio-config')
config = {}

class PutioMounter(Operations):
    def __init__(self):
        global config

        self.putio = putiopy.Client(config['token'])
        self.config = config

    def _set_files(self, folder, files):
        for file in files:
            self._add_file(os.path.join(folder, file.name), file)

    def _add_file(self, fullFileName, file):
        foldersIds[fullFileName.replace(os.path.sep + os.path.sep, os.path.sep).encode('utf-8')] = file

    def _get_id(self, path):
        if path == os.path.sep:
            return 0

        return self._get_file(path).id

    def _get_parent_path(self, path):
        return os.path.split(path)[0]

    def _get_file(self, path):
        path = self._full_path(path)
        try:
            return foldersIds[self._full_path(path)]
        except:
            self.readdir(self._get_parent_path(path), False)
            return foldersIds[self._full_path(path)]

    def _full_path(self, partial):
        return partial.encode('utf-8')

    # Filesystem methods
    # ==================

    def access(self, path, mode):
        full_path = self._full_path(path)

    def chmod(self, path, mode):
        full_path = self._full_path(path)

    def chown(self, path, uid, gid):
        full_path = self._full_path(path)

    def getattr(self, path, fh=None):
        uid = pwd.getpwuid(os.getuid()).pw_uid
        gid = pwd.getpwuid(os.getuid()).pw_gid
        self.now = int(time.time())
        parentPath = self._get_parent_path(path)

        if path == os.path.sep:
            return dict(
                 st_mode=S_IFDIR | 0755,
                 st_size=4096,
                 st_ctime=self.now,
                 st_mtime=self.now,
                 st_uid= os.getuid(),
                 st_gid=os.getuid(),
                 st_atime=0,
                 st_nlink=1
             )
        try:
            file = self._get_file(path)
        except:
            st = os.lstat('a-fake-file-which-not-exists')
            return dict((key, getattr(st, key)) for key in ('st_atime', 'st_ctime',
                     'st_gid', 'st_mode', 'st_mtime', 'st_nlink', 'st_size', 'st_uid'))
        try:
            ctime = time.mktime(file.created_at.timetuple())
        except:
            ctime = self.now

        if isinstance(file, self.putio.Subtitle):
            filepath = file.download('/tmp')
            return dict(
                 st_mode=S_IFREG | 0755,
                 st_size=os.path.getsize(filepath),
                 st_ctime=ctime,
                 st_mtime=ctime,
                 st_atime=0,
                 st_uid=os.getuid(),
                 st_gid=os.getuid(),
                 st_nlink=1
             )
        if file.content_type == 'application/x-directory':
           return dict(
                st_mode=S_IFDIR | 0755,
                st_size=4096,
                st_ctime=ctime,
                st_mtime=ctime,
                st_atime=0,
                st_uid=os.getuid(),
                st_gid=os.getuid(),
                st_nlink=1
            )

        filename, file_extension = os.path.splitext(path)
        filename, origin_file_extension = os.path.splitext(file.name)
        if self.config['use_mp4'] and origin_file_extension != '.mp4' and file_extension == '.mp4':
            size = file.get_mp4_size()
        else:
            size = file.size

        return dict(
            st_mode=S_IFREG | 0755,
            st_size=size,
            st_ctime=ctime,
            st_mtime=ctime,
            st_uid= os.getuid(),
            st_gid=os.getuid(),
            st_atime=0,
            st_nlink=1
        )

    def readdir(self, path, fh):
        full_path = self._full_path(path)
        dirents = ['.', '..']
        if full_path != os.path.sep:
            file = self._get_file(full_path)
            files = file.dir()
        else:
            files = self.putio.File.list();

        for file in files:
            filename = file.name
            dirents.append(filename)
            self._add_file(os.path.join(full_path, filename), file)
            file_name, file_extension = os.path.splitext(filename)

            if file.content_type[:6] == 'video/':
                if self.config['use_subtitles']:
                    subtitles = file.get_subtitles()
                    for subtitle in subtitles:
                        filename_subtitle = subtitle.name
                        self._add_file(os.path.join(full_path, filename_subtitle), subtitle)
                        dirents.append(filename_subtitle)
                if self.config['use_mp4'] and file_extension != '.mp4' and file.is_mp4_available:
                    filename_mp4 = os.path.splitext(filename)[0]+'.mp4'
                    self._add_file(os.path.join(full_path, filename_mp4), file)
                    dirents.append(filename_mp4)
                elif self.config['use_mp4'] and file.content_type != 'video/mp4' and not file.is_mp4_available:
                    file.ask_for_mp4()

        return dirents

    def mkdir(self, path, mode):
        pathInfos = os.path.split(path)
        parentPath = pathInfos[0]
        if (parentPath != os.path.sep):
            parentId = self._get_file(parentPath).id
        else:
            parentId = 0

        self.putio.File.create_folder(pathInfos[1], parentId)

    def statfs(self, path):
        return dict(
                  bsize= 1000000,
                  frsize= 1000000,
                  blocks= 1000000,
                  bfree= 1000000,
                  bavail= 1000000,
                  files= 1000000,
                  ffree= 1000000,
                  favail= 1000000,
                  fsid= 1000000,
                  flag= 1000000,
                  namemax= 1000000
               )
    def unlink(self, path):
        file = self._get_file(path);
        return file.delete()

    def rmdir(self, path):
        file = self._get_file(path);
        file.delete()

    def rename(self, old, new):
        file = self._get_file(old)
        pathInfos = os.path.split(path)
        return file.rename(pathInfos[1])

    # File methods
    # ============

    def open(self, path, flags):
        return True

    def create(self, path, mode, fi=None):
        full_path = self._full_path(path)
        return os.open(full_path, os.O_WRONLY | os.O_CREAT, mode)

    def read(self, path, length, offset, fh):
        try:
            fileUrl = links[path]
        except:
            file = self._get_file(path)
            if isinstance(file, self.putio.Subtitle):
                filepath = file.download('/tmp')
                with open(filepath, 'r') as fp:
                    fp.seek(offset)
                    return fp.read(length)

            filename, file_extension = os.path.splitext(path)
            filename, original_file_extension = os.path.splitext(file.name)

            if self.config['use_mp4'] and original_file_extension != '.mp4' and file_extension == '.mp4':
                fileUrl = file.get_stream_link(prefer_mp4=True)
                size = file.get_mp4_size()
            else:
                fileUrl = file.get_stream_link(prefer_mp4=False)
                size = file.size
        try:
            downloader = downloaders[path]
        except:
            downloader = Downloader(fileUrl, size, file.id)
            downloaders[path] = downloader

        return downloader.read(offset, length, fileUrl, path)

class Downloader:
    packetSize = 1024 * 2048

    def __init__(self, fileUrl, fileSize, fileId):
        self.packets = []

        self.url = fileUrl
        self.size = fileSize
        self.fileId = fileId

    def _create_packet(self, packet, url):
        if os.path.exists(packet.file):
            return packet

        headers = {"Range": 'bytes=%s-%s' % (str(packet.start), str(packet.end - 1))}
        req = requests.get(url, headers=headers, stream=True)

        with open(packet.file, 'w') as fp:
            for chunk in req.iter_content(chunk_size=512):
                if chunk:
                    fp.write(chunk)
                    fp.flush()

                if os.path.getsize(packet.file) >= self.packetSize or fp.tell()  >= self.packetSize:
                    return packet

        return packet

    def _get_packet(self, offset, length, url, path):
        for packet in self.packets:
            if packet.start <= offset and packet.end >= offset + length:
                return packet

        packet = type('lamdbaobject', (object,), {})()
        packet.start = 0
        packet.path = path
        packet.end = self.packetSize
        packet.id = 1

        while packet.end < offset + length:
            packet.start += self.packetSize
            packet.end = packet.start + self.packetSize
            packet.id += 1

        if packet.end > self.size:
            packet.end = self.size

        filename, file_extension = os.path.splitext(path)
        packet.file = os.path.join(tmp_path, '%s-%s%s' % (str(self.fileId), str(packet.start), str(file_extension)))
        if not os.path.exists(packet.file):
            clean_old_files()
            thr = threading.Thread(target=self._create_packet, args=(), kwargs={"packet": packet, "url": url})
            thr.start()

        return packet

    def read(self, offset, length, url, path):
        if offset + length > self.size:
            length = self.size - offset

        packet = self._get_packet(offset, length, url, path)

        if not os.path.exists(packet.file) or os.path.getsize(packet.file) < offset - packet.start + length or packet.end < offset + length or offset - packet.start < 0:
            headers = {"Range": 'bytes=%s-%s' % (str(offset), str(offset + length - 1))}
            return requests.get(url, headers=headers).content

        fp = open(packet.file, 'r')
        fp.seek(offset - packet.start)
        data = fp.read(length)
        fp.close()

        if packet.end < self.size and os.path.getsize(packet.file) >= self.packetSize:
            nextPacket = self._get_packet(packet.end + 1, 2, url, path)

        return data

def clean_old_files() :
    now = time.time()
    for f in os.listdir(tmp_path):
        f = os.path.join(tmp_path, f)
        if os.stat(f).st_atime < now - 60 * 60 and os.path.isfile(f):
            os.remove(f)

def main(mount_point):
    mount(mount_point)

def mount(new_mount_point):
    global mount_point
    global config

    mount_point = new_mount_point
    if not os.path.exists(tmp_path):
        os.makedirs(tmp_path)

    if not os.path.exists(config_file):
        defaultConfig = {
            "token": "YOUR_TOKEN_HERE",
            "use_mp4": False,
            "use_subtitles": False
        }

        with open(config_file, 'w') as f:
            f.write(json.dumps(defaultConfig))

    with open(config_file, 'r') as f:
        config = json.loads(f.read())

    if config['token'] is None or config['token'] == 'YOUR_TOKEN_HERE':
        print "Please put your token in %s file." % config_file
        exit()

    FUSE(PutioMounter(), mount_point, nothreads=False, foreground=False,**{'allow_other': True})
    i = inotify.adapters.Inotify()
    i.add_watch(mount_point)

def get_mount_point():
    global mount_point

    return mount_point

def set_config(paramKey, paramValue):
    global config
    global config_file
    config['paramKey'] = paramValue
    with open(config_file, 'w'):
        f.write(json.dumps(config))

def set_config_file(custom_credentials_path):
    global config_file
    config_file = custom_credentials_path

def set_tmp_path(custom_tmp_path):
    global tmp_path
    tmp_path = custom_tmp_path

if __name__ == '__main__':
    main(sys.argv[1])
<|endoftext|>


<commit_before>#!/usr/bin/python2.4
# -*- mode: python -*-
#
# Copyright (c) 2004-2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

import base64
import errno
import os
import posixpath
import select
import sys
import xmlrpclib
import urllib
import zlib
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

thisFile = sys.modules[__name__].__file__
thisPath = os.path.dirname(thisFile)
if thisPath:
    mainPath = thisPath + "/../.."
else:
    mainPath = "../.."
mainPath = os.path.realpath(mainPath)
sys.path.insert(0, mainPath)
from conary.lib import coveragehook

from conary import dbstore
from conary.lib import options
from conary.lib import util
from conary.lib.cfg import CfgInt
from conary.lib.tracelog import initLog, logMe
from conary.repository import changeset
from conary.repository import errors
from conary.repository.filecontainer import FileContainer
from conary.repository.netrepos import netserver
from conary.repository.netrepos.netserver import NetworkRepositoryServer
from conary.server import schema

#sys.excepthook = util.genExcepthook(debug=True)

class HttpRequests(SimpleHTTPRequestHandler):

    outFiles = {}
    inFiles = {}

    tmpDir = None

    def translate_path(self, path):
        """Translate a /-separated PATH to the local filename syntax.

        Components that mean special things to the local file system
        (e.g. drive or directory names) are ignored.  (XXX They should
        probably be diagnosed.)

        """
        path = posixpath.normpath(urllib.unquote(path))
	path = path.split("?", 1)[1]
        words = path.split('/')
        words = filter(None, words)
        path = self.tmpDir
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir): continue
            path = os.path.join(path, word)

	path += "-out"

	self.cleanup = path
        return path

    def do_GET(self):
        def _writeNestedFile(outF, name, tag, size, f, sizeCb):
            if changeset.ChangedFileTypes.refr[4:] == tag[2:]:
                path = f.read()
                size = os.stat(path).st_size
                f = open(path)
                tag = tag[0:2] + changeset.ChangedFileTypes.file[4:]

            sizeCb(size, tag)
            bytes = util.copyfileobj(f, outF)

        if self.path.endswith('/'):
            self.path = self.path[:-1]
        base = os.path.basename(self.path)
        if "?" in base:
            base, queryString = base.split("?")
        else:
            queryString = ""

        if base == 'changeset':
            urlPath = posixpath.normpath(urllib.unquote(self.path))
            localName = self.tmpDir + "/" + urlPath.split('?', 1)[1] + "-out"
            if os.path.realpath(localName) != localName:
                self.send_error(404, "File not found")
                return None

            if localName.endswith(".cf-out"):
                try:
                    f = open(localName, "r")
                except IOError:
                    self.send_error(404, "File not found")
                    return None

                os.unlink(localName)

                items = []
                totalSize = 0
                for l in f.readlines():
                    (path, size) = l.split()
                    size = int(size)
                    totalSize += size
                    items.append((path, size))
                f.close()
                del f
            else:
                try:
                    size = os.stat(localName).st_size;
                except OSError:
                    self.send_error(404, "File not found")
                    return None
                items = [ (localName, size) ]
                totalSize = size

            self.send_response(200)
            self.send_header("Content-type", "application/octet-stream")
            self.send_header("Content-Length", str(totalSize))
            self.end_headers()

            for path, size in items:
                if path.endswith('.ccs-out'):
                    cs = FileContainer(open(path))
                    cs.dump(self.wfile.write,
                            lambda name, tag, size, f, sizeCb:
                                _writeNestedFile(self.wfile, name, tag, size, f,
                                                 sizeCb))

                    del cs
                    if path.startswith(self.tmpDir):
                        os.unlink(path)
                else:
                    f = open(path)
                    util.copyfileobj(f, self.wfile)
        else:
            self.send_error(501, "Not Implemented")

    def do_POST(self):
        if self.headers.get('Content-Type', '') == 'text/xml':
            authToken = self.getAuth()
            if authToken is None:
                return

            return self.handleXml(authToken)
        else:
            self.send_error(501, "Not Implemented")

    def getAuth(self):
        info = self.headers.get('Authorization', None)
        if info is None:
            httpAuthToken = [ 'anonymous', 'anonymous' ]
        else:
            info = info.split()

            try:
                authString = base64.decodestring(info[1])
            except:
                self.send_error(400)
                return None

            if authString.count(":") != 1:
                self.send_error(400)
                return None

            httpAuthToken = authString.split(":")

        entitlement = self.headers.get('X-Conary-Entitlement', None)
        if entitlement is not None:
            try:
                entitlement = entitlement.split()
                entitlement[1] = base64.decodestring(entitlement[1])
            except:
                self.send_error(400)
                return None
        else:
            entitlement = [ None, None ]

        return httpAuthToken + entitlement

    def checkAuth(self):
 	if not self.headers.has_key('Authorization'):
            self.requestAuth()
            return None
	else:
            authToken = self.getAuth()
            if authToken is None:
                return

	return authToken

    def requestAuth(self):
        self.send_response(401)
        self.send_header("WWW-Authenticate", 'Basic realm="Conary Repository"')
        self.end_headers()
        return None

    def handleXml(self, authToken):
	contentLength = int(self.headers['Content-Length'])
        data = self.rfile.read(contentLength)

        encoding = self.headers.get('Content-Encoding', None)
        if encoding == 'deflate':
            data = zlib.decompress(data)

        (params, method) = xmlrpclib.loads(data)
        logMe(3, "decoded xml-rpc call %s from %d bytes request" %(method, contentLength))

	try:
	    result = netRepos.callWrapper(None, None, method, authToken, params,
                              remoteIp = self.connection.getpeername()[0])
	except errors.InsufficientPermission:
	    self.send_error(403)
	    return None
        logMe(3, "returned from", method)

        usedAnonymous = result[0]
        result = result[1:]

	resp = xmlrpclib.dumps((result,), methodresponse=1)
        logMe(3, "encoded xml-rpc response to %d bytes" % (len(resp),))

	self.send_response(200)
        encoding = self.headers.get('Accept-encoding', '')
        if len(resp) > 200 and 'deflate' in encoding:
            resp = zlib.compress(resp, 5)
            self.send_header('Content-encoding', 'deflate')
	self.send_header("Content-type", "text/xml")
	self.send_header("Content-length", str(len(resp)))
        if usedAnonymous:
            self.send_header("X-Conary-UsedAnonymous", '1')

	self.end_headers()
	self.wfile.write(resp)
        logMe(3, "sent response to client", len(resp), "bytes")
	return resp

    def do_PUT(self):
	path = self.path.split("?")[-1]

        if '/' in path:
	    self.send_error(403, "Forbidden")

	path = self.tmpDir + '/' + path + "-in"

	size = os.stat(path).st_size
	if size != 0:
	    self.send_error(410, "Gone")
	    return

	out = open(path, "w")

	contentLength = int(self.headers['Content-Length'])
	while contentLength:
	    s = self.rfile.read(contentLength)
	    contentLength -= len(s)
	    out.write(s)

	self.send_response(200, 'OK')

class ResetableNetworkRepositoryServer(NetworkRepositoryServer):
    publicCalls = set(tuple(NetworkRepositoryServer.publicCalls) + ('reset',))
    def reset(self, authToken, clientVersion):
        import shutil
        logMe(1, "resetting NetworkRepositoryServer", self.repDB)
        try:
            shutil.rmtree(self.contentsDir[0])
        except OSError, e:
            if e.errno != errno.ENOENT:
                raise
        os.mkdir(self.contentsDir[0])

        # cheap trick. sqlite3 doesn't mind zero byte files; just replace
        # the file with a zero byte one (to change the inode) and reopen
        open(self.repDB[1] + '.new', "w")
        os.rename(self.repDB[1] + '.new', self.repDB[1])
        db = dbstore.connect(self.repDB[1], 'sqlite')
        schema.loadSchema(db)
        db.commit()
        self.reopen()
        self.createUsers()
        return 0

    def createUser(self, name, password, write = False, admin = False,
                   remove = False):
        self.auth.addUser(name, password)
        self.auth.addAcl(name, None, None, write, False, admin, remove = remove)

    def createUsers(self):
        self.createUser('test', 'foo', admin = True, write = True,
                        remove = True)
        self.createUser('anonymous', 'anonymous', admin = False, write = False)

class ServerConfig(netserver.ServerConfig):

    port		= (CfgInt,  8000)

    def __init__(self, path="serverrc"):
	netserver.ServerConfig.__init__(self)
	self.read(path, exception=False)

    def check(self):
        if self.cacheDB:
            print >> sys.stderr, ("warning: cacheDB config option is ignored "
                                  "by the standalone server")

        if self.closed:
            print >> sys.stderr, ("warning: closed config option is ignored "
                                  "by the standalone server")

        if self.forceSSL:
            print >> sys.stderr, ("warning: commitAction config option is "
                                  "ignored by the standalone server")

def usage():
    print "usage: %s" % sys.argv[0]
    print "       %s --add-user <username> [--admin] [--mirror]" % sys.argv[0]
    print "       %s --analyze" % sys.argv[0]
    print ""
    print "server flags: --config-file <path>"
    print '              --db "driver <path>"'
    print '              --log-file <path>'
    print '              --map "<from> <to>"'
    print "              --server-name <host>"
    print "              --tmp-dir <path>"
    sys.exit(1)

def addUser(netRepos, userName, admin = False, mirror = False):
    if os.isatty(0):
        from getpass import getpass

        pw1 = getpass('Password:')
        pw2 = getpass('Reenter password:')

        if pw1 != pw2:
            print "Passwords do not match."
            return 1
    else:
        # chop off the trailing newline
        pw1 = sys.stdin.readline()[:-1]

    # never give anonymous write access by default
    write = userName != 'anonymous'
    netRepos.auth.addUser(userName, pw1)
    # user/group, trovePattern, label, write, capped, admin
    netRepos.auth.addAcl(userName, None, None, write, False, admin)
    netRepos.auth.setMirror(userName, mirror)

if __name__ == '__main__':
    argDef = {}
    cfgMap = {
        'contents-dir'  : 'contentsDir',
	'db'	        : 'repositoryDB',
	'log-file'	: 'logFile',
	'map'	        : 'repositoryMap',
	'port'	        : 'port',
	'tmp-dir'       : 'tmpDir',
        'require-sigs'  : 'requireSigs',
        'server-name'   : 'serverName'
    }

    cfg = ServerConfig()

    argDef["config"] = options.MULT_PARAM
    # magically handled by processArgs
    argDef["config-file"] = options.ONE_PARAM

    argDef['add-user'] = options.ONE_PARAM
    argDef['admin'] = options.NO_PARAM
    argDef['analyze'] = options.NO_PARAM
    argDef['help'] = options.NO_PARAM
    argDef['migrate'] = options.NO_PARAM
    argDef['mirror'] = options.NO_PARAM

    try:
        argSet, otherArgs = options.processArgs(argDef, cfgMap, cfg, usage)
    except options.OptionError, msg:
        print >> sys.stderr, msg
        sys.exit(1)

    if 'migrate' not in argSet:
        cfg.check()

    if argSet.has_key('help'):
        usage()

    if not os.path.isdir(cfg.tmpDir):
	print cfg.tmpDir + " needs to be a directory"
	sys.exit(1)
    if not os.access(cfg.tmpDir, os.R_OK | os.W_OK | os.X_OK):
        print cfg.tmpDir + " needs to allow full read/write access"
        sys.exit(1)
    HttpRequests.tmpDir = cfg.tmpDir

    profile = 0
    if profile:
        import hotshot
        prof = hotshot.Profile('server.prof')
        prof.start()

    baseUrl="http://%s:%s/" % (os.uname()[1], cfg.port)

    # start the logging
    if 'add-user' not in argSet and 'analyze' not in argSet:
        (l, f) = (3, "stderr")
        if cfg.traceLog:
            (l, f) = cfg.traceLog
        initLog(filename = f, level = l, trace=1)

    if not cfg.repositoryDB:
        cfg.repositoryDB = ("sqlite",  "%s/sqldb" % otherArgs[1])
        del otherArgs[1]

    if len(otherArgs) > 1:
	usage()

    if not cfg.contentsDir:
        assert(cfg.repositoryDB[0] == "sqlite")
        cfg.contentsDir = os.path.dirname(cfg.repositoryDB[1]) + '/contents'

    if cfg.repositoryDB[0] == 'sqlite':
        util.mkdirChain(os.path.dirname(cfg.repositoryDB[1]))

    (driver, database) = cfg.repositoryDB
    db = dbstore.connect(database, driver)
    logMe(1, "checking schema version")
    # if there is no schema or we're asked to migrate, loadSchema
    if db.getVersion() == 0 or 'migrate' in argSet:
        schema.loadSchema(db)
    if 'migrate' in argSet:
        sys.exit(0)

    #netRepos = NetworkRepositoryServer(cfg, baseUrl)
    netRepos = ResetableNetworkRepositoryServer(cfg, baseUrl)

    if 'add-user' in argSet:
        admin = argSet.pop('admin', False)
        mirror = argSet.pop('mirror', False)
        userName = argSet.pop('add-user')
        if argSet:
            usage()
        sys.exit(addUser(netRepos, userName, admin = admin, mirror = mirror))
    elif argSet.pop('analyze', False):
        if argSet:
            usage()
        netRepos.db.analyze()
        sys.exit(0)

    if argSet:
        usage()

    httpServer = HTTPServer(("", cfg.port), HttpRequests)

    fds = {}
    fds[httpServer.fileno()] = httpServer

    p = select.poll()
    for fd in fds.iterkeys():
        p.register(fd, select.POLLIN)

    logMe(1, "Server ready for requests")

    while True:
        try:
            events = p.poll()
            for (fd, event) in events:
                fds[fd].handle_request()
        except select.error:
            pass
        except:
            if profile:
                prof.stop()
                print "exception happened, exiting"
                sys.exit(1)
            else:
                raise
<commit_msg>undo bad change<commit_after>#!/usr/bin/python2.4
# -*- mode: python -*-
#
# Copyright (c) 2004-2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

import base64
import errno
import os
import posixpath
import select
import sys
import xmlrpclib
import urllib
import zlib
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

thisFile = sys.modules[__name__].__file__
thisPath = os.path.dirname(thisFile)
if thisPath:
    mainPath = thisPath + "/../.."
else:
    mainPath = "../.."
mainPath = os.path.realpath(mainPath)
sys.path.insert(0, mainPath)
from conary.lib import coveragehook

from conary import dbstore
from conary.lib import options
from conary.lib import util
from conary.lib.cfg import CfgInt
from conary.lib.tracelog import initLog, logMe
from conary.repository import changeset
from conary.repository import errors
from conary.repository.filecontainer import FileContainer
from conary.repository.netrepos import netserver
from conary.repository.netrepos.netserver import NetworkRepositoryServer
from conary.server import schema

#sys.excepthook = util.genExcepthook(debug=True)

class HttpRequests(SimpleHTTPRequestHandler):

    outFiles = {}
    inFiles = {}

    tmpDir = None

    def translate_path(self, path):
        """Translate a /-separated PATH to the local filename syntax.

        Components that mean special things to the local file system
        (e.g. drive or directory names) are ignored.  (XXX They should
        probably be diagnosed.)

        """
        path = posixpath.normpath(urllib.unquote(path))
	path = path.split("?", 1)[1]
        words = path.split('/')
        words = filter(None, words)
        path = self.tmpDir
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir): continue
            path = os.path.join(path, word)

	path += "-out"

	self.cleanup = path
        return path

    def do_GET(self):
        def _writeNestedFile(outF, name, tag, size, f, sizeCb):
            if changeset.ChangedFileTypes.refr[4:] == tag[2:]:
                path = f.read()
                size = os.stat(path).st_size
                f = open(path)
                tag = tag[0:2] + changeset.ChangedFileTypes.file[4:]

            sizeCb(size, tag)
            bytes = util.copyfileobj(f, outF)

        if self.path.endswith('/'):
            self.path = self.path[:-1]
        base = os.path.basename(self.path)
        if "?" in base:
            base, queryString = base.split("?")
        else:
            queryString = ""

        if base == 'changeset':
            urlPath = posixpath.normpath(urllib.unquote(self.path))
            localName = self.tmpDir + "/" + urlPath.split('?', 1)[1] + "-out"
            if os.path.realpath(localName) != localName:
                self.send_error(404, "File not found")
                return None

            if localName.endswith(".cf-out"):
                try:
                    f = open(localName, "r")
                except IOError:
                    self.send_error(404, "File not found")
                    return None

                os.unlink(localName)

                items = []
                totalSize = 0
                for l in f.readlines():
                    (path, size) = l.split()
                    size = int(size)
                    totalSize += size
                    items.append((path, size))
                f.close()
                del f
            else:
                try:
                    size = os.stat(localName).st_size;
                except OSError:
                    self.send_error(404, "File not found")
                    return None
                items = [ (localName, size) ]
                totalSize = size

            self.send_response(200)
            self.send_header("Content-type", "application/octet-stream")
            self.send_header("Content-Length", str(totalSize))
            self.end_headers()

            for path, size in items:
                if path.endswith('.ccs-out'):
                    cs = FileContainer(open(path))
                    cs.dump(self.wfile.write,
                            lambda name, tag, size, f, sizeCb:
                                _writeNestedFile(self.wfile, name, tag, size, f,
                                                 sizeCb))

                    del cs
                    if path.startswith(self.tmpDir):
                        os.unlink(path)
                else:
                    f = open(path)
                    util.copyfileobj(f, self.wfile)
        else:
            self.send_error(501, "Not Implemented")

    def do_POST(self):
        if self.headers.get('Content-Type', '') == 'text/xml':
            authToken = self.getAuth()
            if authToken is None:
                return

            return self.handleXml(authToken)
        else:
            self.send_error(501, "Not Implemented")

    def getAuth(self):
        info = self.headers.get('Authorization', None)
        if info is None:
            httpAuthToken = [ 'anonymous', 'anonymous' ]
        else:
            info = info.split()

            try:
                authString = base64.decodestring(info[1])
            except:
                self.send_error(400)
                return None

            if authString.count(":") != 1:
                self.send_error(400)
                return None

            httpAuthToken = authString.split(":")

        entitlement = self.headers.get('X-Conary-Entitlement', None)
        if entitlement is not None:
            try:
                entitlement = entitlement.split()
                entitlement[1] = base64.decodestring(entitlement[1])
            except:
                self.send_error(400)
                return None
        else:
            entitlement = [ None, None ]

        return httpAuthToken + entitlement

    def checkAuth(self):
 	if not self.headers.has_key('Authorization'):
            self.requestAuth()
            return None
	else:
            authToken = self.getAuth()
            if authToken is None:
                return

	return authToken

    def requestAuth(self):
        self.send_response(401)
        self.send_header("WWW-Authenticate", 'Basic realm="Conary Repository"')
        self.end_headers()
        return None

    def handleXml(self, authToken):
	contentLength = int(self.headers['Content-Length'])
        data = self.rfile.read(contentLength)

        encoding = self.headers.get('Content-Encoding', None)
        if encoding == 'deflate':
            data = zlib.decompress(data)

        (params, method) = xmlrpclib.loads(data)
        logMe(3, "decoded xml-rpc call %s from %d bytes request" %(method, contentLength))

	try:
	    result = netRepos.callWrapper(None, None, method, authToken, params,
                              remoteIp = self.connection.getpeername()[0])
	except errors.InsufficientPermission:
	    self.send_error(403)
	    return None
        logMe(3, "returned from", method)

        usedAnonymous = result[0]
        result = result[1:]

	resp = xmlrpclib.dumps((result,), methodresponse=1)
        logMe(3, "encoded xml-rpc response to %d bytes" % (len(resp),))

	self.send_response(200)
        encoding = self.headers.get('Accept-encoding', '')
        if len(resp) > 200 and 'deflate' in encoding:
            resp = zlib.compress(resp, 5)
            self.send_header('Content-encoding', 'deflate')
	self.send_header("Content-type", "text/xml")
	self.send_header("Content-length", str(len(resp)))
        if usedAnonymous:
            self.send_header("X-Conary-UsedAnonymous", '1')

	self.end_headers()
	self.wfile.write(resp)
        logMe(3, "sent response to client", len(resp), "bytes")
	return resp

    def do_PUT(self):
	path = self.path.split("?")[-1]

        if '/' in path:
	    self.send_error(403, "Forbidden")

	path = self.tmpDir + '/' + path + "-in"

	size = os.stat(path).st_size
	if size != 0:
	    self.send_error(410, "Gone")
	    return

	out = open(path, "w")

	contentLength = int(self.headers['Content-Length'])
	while contentLength:
	    s = self.rfile.read(contentLength)
	    contentLength -= len(s)
	    out.write(s)

	self.send_response(200, 'OK')

class ResetableNetworkRepositoryServer(NetworkRepositoryServer):
    publicCalls = set(tuple(NetworkRepositoryServer.publicCalls) + ('reset',))
    def reset(self, authToken, clientVersion):
        import shutil
        logMe(1, "resetting NetworkRepositoryServer", self.repDB)
        try:
            shutil.rmtree(self.contentsDir[0])
        except OSError, e:
            if e.errno != errno.ENOENT:
                raise
        os.mkdir(self.contentsDir[0])

        # cheap trick. sqlite3 doesn't mind zero byte files; just replace
        # the file with a zero byte one (to change the inode) and reopen
        open(self.repDB[1] + '.new', "w")
        os.rename(self.repDB[1] + '.new', self.repDB[1])
        db = dbstore.connect(self.repDB[1], 'sqlite')
        schema.loadSchema(db)
        db.commit()
        self.reopen()
        self.createUsers()
        return 0

    def createUser(self, name, password, write = False, admin = False,
                   remove = False):
        self.auth.addUser(name, password)
        self.auth.addAcl(name, None, None, write, False, admin, remove = remove)

    def createUsers(self):
        self.createUser('test', 'foo', admin = True, write = True,
                        remove = True)
        self.createUser('anonymous', 'anonymous', admin = False, write = False)

class ServerConfig(netserver.ServerConfig):

    port		= (CfgInt,  8000)

    def __init__(self, path="serverrc"):
	netserver.ServerConfig.__init__(self)
	self.read(path, exception=False)

    def check(self):
        if self.cacheDB:
            print >> sys.stderr, ("warning: cacheDB config option is ignored "
                                  "by the standalone server")

        if self.closed:
            print >> sys.stderr, ("warning: closed config option is ignored "
                                  "by the standalone server")

        if self.forceSSL:
            print >> sys.stderr, ("warning: commitAction config option is "
                                  "ignored by the standalone server")

def usage():
    print "usage: %s" % sys.argv[0]
    print "       %s --add-user <username> [--admin] [--mirror]" % sys.argv[0]
    print "       %s --analyze" % sys.argv[0]
    print ""
    print "server flags: --config-file <path>"
    print '              --db "driver <path>"'
    print '              --log-file <path>'
    print '              --map "<from> <to>"'
    print "              --server-name <host>"
    print "              --tmp-dir <path>"
    sys.exit(1)

def addUser(netRepos, userName, admin = False, mirror = False):
    if os.isatty(0):
        from getpass import getpass

        pw1 = getpass('Password:')
        pw2 = getpass('Reenter password:')

        if pw1 != pw2:
            print "Passwords do not match."
            return 1
    else:
        # chop off the trailing newline
        pw1 = sys.stdin.readline()[:-1]

    # never give anonymous write access by default
    write = userName != 'anonymous'
    netRepos.auth.addUser(userName, pw1)
    # user/group, trovePattern, label, write, capped, admin
    netRepos.auth.addAcl(userName, None, None, write, False, admin)
    netRepos.auth.setMirror(userName, mirror)

if __name__ == '__main__':
    argDef = {}
    cfgMap = {
        'contents-dir'  : 'contentsDir',
	'db'	        : 'repositoryDB',
	'log-file'	: 'logFile',
	'map'	        : 'repositoryMap',
	'port'	        : 'port',
	'tmp-dir'       : 'tmpDir',
        'require-sigs'  : 'requireSigs',
        'server-name'   : 'serverName'
    }

    cfg = ServerConfig()

    argDef["config"] = options.MULT_PARAM
    # magically handled by processArgs
    argDef["config-file"] = options.ONE_PARAM

    argDef['add-user'] = options.ONE_PARAM
    argDef['admin'] = options.NO_PARAM
    argDef['analyze'] = options.NO_PARAM
    argDef['help'] = options.NO_PARAM
    argDef['migrate'] = options.NO_PARAM
    argDef['mirror'] = options.NO_PARAM

    try:
        argSet, otherArgs = options.processArgs(argDef, cfgMap, cfg, usage)
    except options.OptionError, msg:
        print >> sys.stderr, msg
        sys.exit(1)

    if 'migrate' not in argSet:
        cfg.check()

    if argSet.has_key('help'):
        usage()

    if not os.path.isdir(cfg.tmpDir):
	print cfg.tmpDir + " needs to be a directory"
	sys.exit(1)
    if not os.access(cfg.tmpDir, os.R_OK | os.W_OK | os.X_OK):
        print cfg.tmpDir + " needs to allow full read/write access"
        sys.exit(1)
    HttpRequests.tmpDir = cfg.tmpDir

    profile = 0
    if profile:
        import hotshot
        prof = hotshot.Profile('server.prof')
        prof.start()

    baseUrl="http://%s:%s/" % (os.uname()[1], cfg.port)

    # start the logging
    if 'add-user' not in argSet and 'analyze' not in argSet:
        (l, f) = (3, "stderr")
        if cfg.traceLog:
            (l, f) = cfg.traceLog
        initLog(filename = f, level = l, trace=1)

    if not cfg.repositoryDB:
        cfg.repositoryDB = ("sqlite",  "%s/sqldb" % otherArgs[1])
        del otherArgs[1]

    if len(otherArgs) > 1:
	usage()

    if not cfg.contentsDir:
        assert(cfg.repositoryDB[0] == "sqlite")
        cfg.contentsDir = os.path.dirname(cfg.repositoryDB[1]) + '/contents'

    if cfg.repositoryDB[0] == 'sqlite':
        util.mkdirChain(os.path.dirname(cfg.repositoryDB[1]))

    (driver, database) = cfg.repositoryDB
    db = dbstore.connect(database, driver)
    logMe(1, "checking schema version")
    # if there is no schema or we're asked to migrate, loadSchema
    if db.getVersion() == 0 or 'migrate' in argSet:
        schema.loadSchema(db)
    if 'migrate' in argSet:
        sys.exit(0)

    netRepos = NetworkRepositoryServer(cfg, baseUrl)
    #netRepos = ResetableNetworkRepositoryServer(cfg, baseUrl)

    if 'add-user' in argSet:
        admin = argSet.pop('admin', False)
        mirror = argSet.pop('mirror', False)
        userName = argSet.pop('add-user')
        if argSet:
            usage()
        sys.exit(addUser(netRepos, userName, admin = admin, mirror = mirror))
    elif argSet.pop('analyze', False):
        if argSet:
            usage()
        netRepos.db.analyze()
        sys.exit(0)

    if argSet:
        usage()

    httpServer = HTTPServer(("", cfg.port), HttpRequests)

    fds = {}
    fds[httpServer.fileno()] = httpServer

    p = select.poll()
    for fd in fds.iterkeys():
        p.register(fd, select.POLLIN)

    logMe(1, "Server ready for requests")

    while True:
        try:
            events = p.poll()
            for (fd, event) in events:
                fds[fd].handle_request()
        except select.error:
            pass
        except:
            if profile:
                prof.stop()
                print "exception happened, exiting"
                sys.exit(1)
            else:
                raise
<|endoftext|>