tecknojock

dumpalllogs.py

Aug 25th, 2014
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.26 KB | None | 0 0
  1. #!/usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3.  
  4. # Copyright 2008 Ramon Klass <[email protected]>
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. """Description:
  20. dumplog.py dumps Quassel logs to files suitable for pisg (irc statistics generator)
  21.  
  22. Usage:
  23. dumplog.py [-d dbfile] -u user [-n network] [-c channel] [-o logfile]
  24.  
  25. anything except -u is optional, default dbfile is ~/.quassel/quassel-storage.sqlite
  26. if any options are missing, an appropriate action is executed.
  27.  
  28. Examples:
  29. "dumplog.py -u somebody" lists all networks the user somebody is on
  30. "dumplog.py -u somebody -n Freenode" lists all buffers on network Freenode for user somebody"""
  31.  
  32. from optparse import OptionParser
  33. import os.path
  34. import quasseltool
  35. import codecs
  36. import sys
  37. import re
  38.  
  39. reload(sys)
  40. sys.setdefaultencoding('utf8')
  41.  
  42. class Consolecounter:
  43. def __init__(self, head=None, tail=None):
  44. self.started = False
  45. self.head = head
  46. self.tail = tail
  47.  
  48. def set_max(self, num):
  49. if not self.started:
  50. self.num = num
  51. self.numlen = len(str(num))
  52.  
  53. def start(self):
  54. if not self.started:
  55. self.i = 0
  56. if not self.head is None:
  57. sys.stdout.write(self.head)
  58. for x in xrange(self.numlen):
  59. sys.stdout.write(" ")
  60. sys.stdout.write(" ")
  61. sys.stdout.flush()
  62. self.started = True
  63.  
  64. def next(self):
  65. if self.started:
  66. self.i += 1
  67. for x in xrange(self.numlen):
  68. sys.stdout.write("\b\b")
  69. sys.stdout.write("\b")
  70. sys.stdout.write(str(self.i).rjust(self.numlen, " "))
  71. sys.stdout.write("/")
  72. sys.stdout.write(str(self.num))
  73. sys.stdout.flush()
  74. if self.i >= self.num:
  75. if not self.tail is None:
  76. sys.stdout.write(self.tail)
  77. sys.stdout.flush()
  78. def last_line(in_file, block_size=1024, ignore_ending_newline=True):
  79. suffix = ""
  80. in_file.seek(0, os.SEEK_END)
  81. in_file_length = in_file.tell()
  82. seek_offset = 0
  83.  
  84. while(-seek_offset < in_file_length):
  85. # Read from end.
  86. seek_offset -= block_size
  87. if -seek_offset > in_file_length:
  88. # Limit if we ran out of file (can't seek backward from start).
  89. block_size -= -seek_offset - in_file_length
  90. if block_size == 0:
  91. break
  92. seek_offset = -in_file_length
  93. in_file.seek(seek_offset, os.SEEK_END)
  94. buf = in_file.read(block_size)
  95.  
  96. # Search for line end.
  97. if ignore_ending_newline and seek_offset == -block_size and buf[-1] == '\n':
  98. buf = buf[:-1]
  99. pos = buf.rfind('\n')
  100. if pos != -1:
  101. # Found line end.
  102. return buf[pos+1:] + suffix
  103.  
  104. suffix = buf + suffix
  105.  
  106. # One-line file.
  107. return suffix
  108. class App():
  109. def __init__(self):
  110. self._init_opts()
  111. self._run()
  112.  
  113. def _init_opts(self):
  114. parser = OptionParser(usage="%prog [-d DB] [-u USER] [-n NETWORK] [-c CHANNEL] [-o OUT]", version="%prog 0.0.1", description="""Quassel Logfile dumper currently exports mirc logs suitable for pisg. Default for DB is ~/.quassel/quassel-storage.sqlite. Run without options for more info""")
  115. parser.add_option("-d", "--db", action="store", type="string", default="", help="DB file to use")
  116. parser.add_option("-u", "--user", action="store", type="string", default="", help="quassel username")
  117. parser.add_option("-n", "--network", action="store", type="string", default="", help="IRC network")
  118. parser.add_option("-c", "--channel", action="store", type="string", default="", help="IRC channel/quassel buffer")
  119. parser.add_option("-o", "--out", action="store", type="string", default="", help="output file")
  120. (self.opts, self.args) = parser.parse_args()
  121.  
  122. def _run(self):
  123. self.log = quasseltool.Logutil()
  124. #try:
  125. #
  126. # if self.opts.db == "":
  127. # dbname = "(defaults)"
  128. # else:
  129. # dbname = self.opts.db
  130. # print "FATAL: Unable to open db file %s"%os.path.expanduser(dbname)
  131. # print "if it is somewhere else, use the -d FILE option"
  132. # sys.exit(1)
  133. if self.opts.user == "":
  134. print "No user specified. Available options are:"
  135. for user in self.log.get_users():
  136. print user
  137. print "\nUse -u USER to choose one"
  138. sys.exit(0)
  139. if not self.log.is_user(self.opts.user):
  140. print "FATAL: User %s does not exist in DB"%self.opts.user
  141. sys.exit(1)
  142. if self.opts.out == "":
  143. print "No outfile specified. use -o filepath to do so.\nFiles will be overwritten if it exists"
  144. sys.exit(0)
  145. for network in self.log.get_networks(self.opts.user):
  146. self.opts.network = network
  147. for channel in self.log.get_buffers(self.opts.user, self.opts.network):
  148. self.opts.channel = channel
  149. if channel == "":
  150. channel = "Buffer"
  151. try:
  152. os.stat(self.opts.out + network)
  153. except:
  154. os.mkdir(self.opts.out + network)
  155. channel = re.sub(">", "", channel)
  156. filename = os.path.expanduser(self.opts.out + network + '/' + channel + ".log")
  157. if os.path.isfile(filename):
  158. exists = True
  159. else:
  160. exists = False
  161. outfile = codecs.open(filename, "a+", "iso8859_15", errors="replace")
  162. if exists:
  163. #read time and date on last line of file so that the entire buffer wont have to be dumped again and can instead just be appended.
  164. lastline = unicode(last_line(outfile))
  165. time= re.search("\A\[\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}\]",lastline)
  166. if time:
  167. time = time.group(0)[1:-1]+u".999"
  168. #outfile = codecs.open(filename, "wb", "utf-8")
  169. sys.stdout.write("Writing Logfile %s of channel %s on network %s for user %s... "%(filename, self.opts.channel, self.opts.network, self.opts.user))
  170. sys.stdout.flush()
  171. counter = Consolecounter("", "\nDone\n")
  172. self.log.getlog(self.opts.user, self.opts.network, self.opts.channel, outfile, counter=counter, log=self.log, time=time,)
  173. outfile.close()
  174.  
  175. if __name__ == "__main__":
  176. App()
Advertisement
Add Comment
Please, Sign In to add comment