<s> import re <EOL> import os <EOL> import stat <EOL> import json <EOL> import struct <EOL> import time <EOL> import Config <EOL> import Board <EOL> import Post <EOL> import BoardManager <EOL> from Util import Util <EOL> from Log import Log <EOL> from errors import * <EOL> DEFAULT_DIGEST_LIST_COUNT = <NUM_LIT:20> <EOL> class DigestItem : <EOL> def __init__ ( self , basepath ) : <EOL> self . basepath = basepath <EOL> self . title = '<STR_LIT>' <EOL> self . host = '<STR_LIT>' <EOL> self . port = <NUM_LIT:0> <EOL> self . attachpos = <NUM_LIT:0> <EOL> self . fname = '<STR_LIT>' <EOL> self . mtitle = '<STR_LIT>' <EOL> self . items = [ ] <EOL> self . update_time = <NUM_LIT:0> <EOL> self . id = <NUM_LIT:0> <EOL> self . sysop_only = <NUM_LIT:0> <EOL> self . bms_only = <NUM_LIT:0> <EOL> self . zixia_only = <NUM_LIT:0> <EOL> def IsDir ( self ) : <EOL> try : <EOL> st = os . stat ( self . realpath ( ) ) <EOL> return stat . S_ISDIR ( st . st_mode ) <EOL> except : <EOL> return False <EOL> def IsFile ( self ) : <EOL> try : <EOL> st = os . stat ( self . realpath ( ) ) <EOL> return stat . S_ISREG ( st . st_mode ) <EOL> except : <EOL> return False <EOL> def GetModTime ( self ) : <EOL> try : <EOL> st = os . stat ( self . realpath ( ) ) <EOL> mtime = st . st_mtime <EOL> except : <EOL> mtime = time . time ( ) <EOL> return mtime <EOL> def names_path ( self ) : <EOL> return "<STR_LIT>" % self . realpath ( ) <EOL> def realpath ( self ) : <EOL> return "<STR_LIT>" % ( Config . BBS_ROOT , self . path ( ) ) <EOL> def path ( self ) : <EOL> if ( self . fname ) : <EOL> return "<STR_LIT>" % ( self . basepath , self . fname ) <EOL> else : <EOL> return self . basepath <EOL> def CheckUpdate ( self ) : <EOL> try : <EOL> stat = os . stat ( self . names_path ( ) ) <EOL> if ( stat . st_mtime > self . update_time ) : <EOL> self . LoadNames ( ) <EOL> except : <EOL> return False <EOL> return True <EOL> def LoadNames ( self ) : <EOL> try : <EOL> f = open ( self . names_path ( ) , "<STR_LIT:r>" ) <EOL> except IOError : <EOL> return <NUM_LIT:0> <EOL> stat = os . fstat ( f . fileno ( ) ) <EOL> self . update_time = stat . st_mtime <EOL> item = DigestItem ( self . path ( ) ) <EOL> hostname = '<STR_LIT>' <EOL> _id = <NUM_LIT:0> <EOL> bms_only = <NUM_LIT:0> <EOL> sysop_only = <NUM_LIT:0> <EOL> zixia_only = <NUM_LIT:0> <EOL> while ( True ) : <EOL> line = f . readline ( ) <EOL> if ( line == "<STR_LIT>" ) : break <EOL> npos = line . find ( "<STR_LIT:\n>" ) <EOL> if ( npos != - <NUM_LIT:1> ) : line = line [ : npos ] <EOL> if ( line [ : <NUM_LIT:1> ] == '<STR_LIT:#>' ) : <EOL> if ( line [ : <NUM_LIT:8> ] == "<STR_LIT>" ) : <EOL> if ( not self . mtitle ) : <EOL> self . mtitle = line [ <NUM_LIT:8> : ] <EOL> result = re . match ( '<STR_LIT>' , line ) <EOL> if ( result ) : <EOL> key = result . group ( <NUM_LIT:1> ) <EOL> value = result . group ( <NUM_LIT:2> ) <EOL> if ( key == "<STR_LIT:Name>" ) : <EOL> item . title = value <EOL> item . attachpos = <NUM_LIT:0> <EOL> elif ( key == "<STR_LIT>" ) : <EOL> if ( value [ : <NUM_LIT:2> ] == "<STR_LIT>" ) : <EOL> item . fname = value [ <NUM_LIT:2> : ] <EOL> else : <EOL> item . fname = value <EOL> if ( item . fname . find ( "<STR_LIT:..>" ) != - <NUM_LIT:1> ) : <EOL> continue <EOL> if ( item . title . find ( "<STR_LIT>" ) != - <NUM_LIT:1> ) : <EOL> bms_only += <NUM_LIT:1> <EOL> elif ( item . title . find ( "<STR_LIT>" ) != - <NUM_LIT:1> ) : <EOL> sysop_only += <NUM_LIT:1> <EOL> elif ( item . title . find ( "<STR_LIT>" ) != - <NUM_LIT:1> ) : <EOL> zixia_only += <NUM_LIT:1> <EOL> if ( item . fname . find ( "<STR_LIT>" ) != - <NUM_LIT:1> ) : <EOL> parts = re . split ( '<STR_LIT>' , item . fname ) <EOL> newparts = [ ] <EOL> for part in parts : <EOL> if ( part ) : <EOL> newparts += [ part ] <EOL> hostname = newparts [ <NUM_LIT:0> ] <EOL> item . fname = newparts [ <NUM_LIT:1> ] <EOL> try : <EOL> item . port = int ( newparts [ <NUM_LIT:2> ] ) <EOL> except : <EOL> item . port = <NUM_LIT:0> <EOL> item . id = _id <EOL> _id += <NUM_LIT:1> <EOL> item . bms_only = bms_only <EOL> item . sysop_only = sysop_only <EOL> item . zixia_only = zixia_only <EOL> item . host = hostname <EOL> self . items += [ item ] <EOL> item = DigestItem ( self . path ( ) ) <EOL> hostname = '<STR_LIT>' <EOL> elif ( key == "<STR_LIT>" ) : <EOL> hostname = value <EOL> elif ( key == "<STR_LIT>" ) : <EOL> try : <EOL> item . port = int ( value ) <EOL> except : <EOL> item . port = <NUM_LIT:0> <EOL> elif ( key == "<STR_LIT>" ) : <EOL> try : <EOL> item . attachpos = int ( value ) <EOL> except : <EOL> item . attachpos = <NUM_LIT:0> <EOL> f . close ( ) <EOL> return <NUM_LIT:1> <EOL> def GetItem ( self , user , route , has_perm = False , need_perm = False ) : <EOL> self . CheckUpdate ( ) <EOL> if ( self . mtitle . find ( "<STR_LIT>" ) != - <NUM_LIT:1> ) : <EOL> if ( Board . Board . IsBM ( user , self . mtitle [ <NUM_LIT:4> : ] , ) or user . IsSysop ( ) ) : <EOL> has_perm = True <EOL> elif ( need_perm and not has_perm ) : <EOL> return None <EOL> if ( self . mtitle . find ( "<STR_LIT>" ) != - <NUM_LIT:1> <EOL> or self . mtitle . find ( "<STR_LIT>" ) != - <NUM_LIT:1> <EOL> or self . mtitle . find ( "<STR_LIT>" ) != - <NUM_LIT:1> ) : <EOL> need_perm = True <EOL> if ( len ( route ) == <NUM_LIT:0> ) : <EOL> return self <EOL> target = route [ <NUM_LIT:0> ] - <NUM_LIT:1> <EOL> _id = target <EOL> if ( _id >= len ( self . items ) ) : <EOL> return None <EOL> while ( self . items [ _id ] . EffectiveId ( user ) < target ) : <EOL> _id += <NUM_LIT:1> <EOL> if ( _id >= len ( self . items ) ) : <EOL> return None <EOL> item = self . items [ _id ] <EOL> item . mtitle = item . title <EOL> if ( len ( route ) == <NUM_LIT:1> ) : <EOL> return item <EOL> else : <EOL> if ( item . IsDir ( ) ) : <EOL> if ( not item . CheckUpdate ( ) ) : <EOL> return None <EOL> return item . GetItem ( user , route [ <NUM_LIT:1> : ] , has_perm , need_perm ) <EOL> else : <EOL> return None <EOL> def GetRange ( self , user , route , start , end , has_perm = False , need_perm = False ) : <EOL> self . CheckUpdate ( ) <EOL> firstitem = self . GetItem ( user , route + [ start ] , has_perm , need_perm ) <EOL> if ( not firstitem ) : <EOL> return [ ] <EOL> parent = self . GetItem ( user , route , has_perm , need_perm ) <EOL> if ( not parent ) : <EOL> return [ ] <EOL> if ( not parent . IsDir ( ) ) : <EOL> return [ ] <EOL> result = [ ] <EOL> _id = start - <NUM_LIT:1> <EOL> for i in range ( start , end + <NUM_LIT:1> ) : <EOL> target = i - <NUM_LIT:1> <EOL> if ( _id >= len ( parent . items ) ) : <EOL> return [ ] <EOL> while ( parent . items [ _id ] . EffectiveId ( user ) < target ) : <EOL> _id += <NUM_LIT:1> <EOL> if ( _id >= len ( parent . items ) ) : <EOL> return result <EOL> item = parent . items [ _id ] <EOL> item . mtitle = item . title <EOL> result += [ item ] <EOL> return result <EOL> def EffectiveId ( self , user ) : <EOL> _id = self . id <EOL> if ( user . IsSysop ( ) ) : <EOL> return _id <EOL> if ( not user . IsSysop ( ) ) : <EOL> _id -= self . sysop_only <EOL> if ( not user . IsBM ( ) ) : <EOL> _id -= self . bms_only <EOL> if ( not user . IsSECANC ( ) ) : <EOL> _id -= self . zixia_only <EOL> return _id <EOL> def GetInfo ( self ) : <EOL> info = { } <EOL> info [ '<STR_LIT>' ] = Util . gbkDec ( self . mtitle ) <EOL> info [ '<STR_LIT:title>' ] = Util . gbkDec ( self . title ) <EOL> info [ '<STR_LIT>' ] = self . attachpos <EOL> if ( self . host != '<STR_LIT>' ) : <EOL> info [ '<STR_LIT:host>' ] = self . host <EOL> info [ '<STR_LIT:port>' ] = self . port <EOL> info [ '<STR_LIT:type>' ] = '<STR_LIT>' <EOL> elif ( self . IsDir ( ) ) : <EOL> info [ '<STR_LIT:type>' ] = '<STR_LIT>' <EOL> elif ( self . IsFile ( ) ) : <EOL> info [ '<STR_LIT:type>' ] = '<STR_LIT:file>' <EOL> else : <EOL> info [ '<STR_LIT:type>' ] = '<STR_LIT>' <EOL> info [ '<STR_LIT>' ] = int ( self . GetModTime ( ) ) <EOL> return info <EOL> def GetInfoForUser ( self , user ) : <EOL> info = self . GetInfo ( ) <EOL> info [ '<STR_LIT:id>' ] = self . EffectiveId ( user ) + <NUM_LIT:1> <EOL> return info <EOL> def GetAttachLink ( self , session ) : <EOL> _hash = Util . HashGen ( self . path ( ) , "<STR_LIT>" ) <EOL> filename = '<STR_LIT>' <EOL> for i in range ( <NUM_LIT:2> ) : <EOL> filename += "<STR_LIT>" % struct . unpack ( '<STR_LIT>' , _hash [ i * <NUM_LIT:4> : ( i + <NUM_LIT:1> ) * <NUM_LIT:4> ] ) <EOL> link = "<STR_LIT>" % ( session . GetMirror ( Config . Config . GetInt ( '<STR_LIT>' , <NUM_LIT> ) ) , filename ) <EOL> linkfile = "<STR_LIT>" % ( Config . BBS_ROOT , filename ) <EOL> target = "<STR_LIT>" % self . path ( ) <EOL> try : <EOL> os . symlink ( target , linkfile ) <EOL> except : <EOL> pass <EOL> return link <EOL> class Digest : <EOL> root = DigestItem ( "<STR_LIT>" ) <EOL> def __init__ ( self , board , path ) : <EOL> self . board = board <EOL> self . path = path <EOL> self . root = DigestItem ( self . path ) <EOL> @ staticmethod <EOL> def GET ( svc , session , params , action ) : <EOL> if ( session is None ) : raise Unauthorized ( '<STR_LIT>' ) <EOL> if not session . CheckScope ( '<STR_LIT>' ) : raise NoPerm ( "<STR_LIT>" ) <EOL> user = session . GetUser ( ) <EOL> boardname = svc . get_str ( params , '<STR_LIT>' , '<STR_LIT>' ) <EOL> if ( boardname ) : <EOL> board = BoardManager . BoardManager . GetBoard ( boardname ) <EOL> if ( board is None ) : raise NotFound ( '<STR_LIT>' % boardname ) <EOL> if ( not board . CheckReadPerm ( user ) ) : <EOL> raise NoPerm ( '<STR_LIT>' ) <EOL> basenode = board . digest . root <EOL> has_perm = user . IsDigestMgr ( ) or user . IsSysop ( ) or user . IsSuperBM ( ) <EOL> else : <EOL> basenode = Digest . root <EOL> has_perm = user . IsDigestMgr ( ) <EOL> if ( action == "<STR_LIT:list>" ) : <EOL> route = svc . get_str ( params , '<STR_LIT>' ) <EOL> start = svc . get_int ( params , '<STR_LIT:start>' , <NUM_LIT:1> ) <EOL> end = svc . get_int ( params , '<STR_LIT:end>' , start + DEFAULT_DIGEST_LIST_COUNT - <NUM_LIT:1> ) <EOL> Digest . List ( svc , basenode , route , start , end , session , has_perm ) <EOL> return <EOL> elif ( action == "<STR_LIT>" ) : <EOL> route = svc . get_str ( params , '<STR_LIT>' ) <EOL> start = svc . get_int ( params , '<STR_LIT:start>' , <NUM_LIT:0> ) <EOL> count = svc . get_int ( params , '<STR_LIT:count>' , <NUM_LIT:0> ) <EOL> Digest . View ( svc , basenode , route , session , has_perm , start , count ) <EOL> return <EOL> else : <EOL> raise WrongArgs ( '<STR_LIT>' % action ) <EOL> @ staticmethod <EOL> def ParseRoute ( route ) : <EOL> ret = [ ] <EOL> items = re . split ( '<STR_LIT:->' , route ) <EOL> items = items [ <NUM_LIT:1> : ] <EOL> for item in items : <EOL> try : <EOL> ret += [ int ( item ) ] <EOL> except : <EOL> raise WrongArgs ( '<STR_LIT>' % item ) <EOL> return ret <EOL> @ staticmethod <EOL> def List ( svc , basenode , route , start , end , session , has_perm ) : <EOL> route_array = Digest . ParseRoute ( route ) <EOL> parent = basenode . GetItem ( session . GetUser ( ) , route_array , has_perm ) <EOL> if ( not parent ) : <EOL> raise WrongArgs ( '<STR_LIT>' % route ) <EOL> if ( not parent . IsDir ( ) ) : <EOL> raise WrongArgs ( '<STR_LIT>' % route ) <EOL> items = basenode . GetRange ( session . GetUser ( ) , route_array , start , end , has_perm ) <EOL> result = { } <EOL> result [ '<STR_LIT>' ] = parent . GetInfoForUser ( session . GetUser ( ) ) <EOL> result [ '<STR_LIT:count>' ] = len ( items ) <EOL> result_list = [ ] <EOL> for item in items : <EOL> result_list += [ item . GetInfoForUser ( session . GetUser ( ) ) ] <EOL> result [ '<STR_LIT>' ] = result_list <EOL> svc . writedata ( json . dumps ( result ) ) <EOL> @ staticmethod <EOL> def View ( svc , basenode , route , session , has_perm , start , count ) : <EOL> route_array = Digest . ParseRoute ( route ) <EOL> item = basenode . GetItem ( session . GetUser ( ) , route_array , has_perm ) <EOL> if ( not item ) : <EOL> raise WrongArgs ( '<STR_LIT>' % route ) <EOL> if ( not item . IsFile ( ) ) : <EOL> raise WrongArgs ( '<STR_LIT>' % route ) <EOL> result = { } <EOL> result [ '<STR_LIT>' ] = item . GetInfoForUser ( session . GetUser ( ) ) <EOL> postinfo = Post . Post ( item . realpath ( ) , None ) <EOL> ( result [ '<STR_LIT:content>' ] , result [ '<STR_LIT>' ] ) = postinfo . GetContent ( start , count ) <EOL> attachlist = postinfo . GetAttachListByType ( ) <EOL> result [ '<STR_LIT>' ] = attachlist [ <NUM_LIT:0> ] <EOL> result [ '<STR_LIT>' ] = attachlist [ <NUM_LIT:1> ] <EOL> if ( attachlist [ <NUM_LIT:0> ] or attachlist [ <NUM_LIT:1> ] ) : <EOL> result [ '<STR_LIT>' ] = item . GetAttachLink ( session ) <EOL> svc . writedata ( json . dumps ( result ) ) </s>
