Gfy

Origons add movie lib

Gfy
Aug 9th, 2011
141
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2. # -*- coding: latin-1 -*-
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16. # MA 02110-1301, USA.
  17.  
  18. import urllib
  19. import urllib2
  20. import cookielib
  21. import re
  22.  
  23. __version__ = "2011-02-17"
  24.  
  25. # some configuration options
  26. _PROXY = False
  27. _PROXY_TYPE = "http"
  28. _PROXY_URL = "http://localhost:8008"
  29.  
  30. class Origons3(object):
  31.     """ Class that supports adding movies on
  32.        origons.com version 3. """
  33.     def __init__(self, username, password):
  34.         self.user_agent = "Gfy's movie add script version %s." % __version__
  35.         cj = cookielib.CookieJar()
  36.        
  37.         # set up proxy to check sent requests with WebScarab
  38.         if _PROXY:
  39.             proxy_support = urllib2.ProxyHandler({_PROXY_TYPE : _PROXY_URL})
  40.             self.opener = urllib2.build_opener(proxy_support)
  41.             urllib2.install_opener(self.opener)
  42.            
  43.             # http://www.daniweb.com/forums/thread144082.html
  44.             self.opener.add_handler(urllib2.HTTPCookieProcessor(cj))
  45.         else:
  46.             self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
  47.             urllib2.install_opener(self.opener)
  48.              
  49.         # save a cookie
  50.         #self.opener.open('http://www.origons.com')
  51.        
  52.         self.baseurl = "http://www.origons.com/"
  53.         self.body = {
  54.                 'username' : username,
  55.                 'password' : password,
  56.                 }
  57.         self.headers = {
  58.                 'Referer' : self.baseurl,
  59.                 'User-Agent' : self.user_agent,
  60.                 }
  61.         self._login()
  62.  
  63.     def _login(self):
  64.         """ Authenticate. """  
  65.         try:
  66.             data = urllib.urlencode(self.body)
  67.             request = urllib2.Request(
  68.                 self.baseurl + "check_pass.asp", data, self.headers)
  69.             handle = self.opener.open(request)
  70.  
  71.             HTMLSource = handle.read()
  72.            
  73.             if re.findall(".*Add to Requests.*", HTMLSource):
  74.                 print("Authentication successful.")
  75.             else:
  76.                 print("Authentication unsuccessful.") # or the site has changed
  77.  
  78.         except (urllib2.URLError, urllib2.HTTPError), e:
  79.             if hasattr(e, 'code'):
  80.                 print 'We failed with error code - %s.' % e.code
  81.             elif hasattr(e, 'reason'):
  82.                 print "The error object has the following 'reason' attribute :", e.reason
  83.                 print "This usually means the server doesn't exist, is down, " + \
  84.                     "or we don't have an Internet connection."
  85.             raise Exception("Login failed: %s" % e)
  86.        
  87.     def list_details(self):
  88.         """ Returns ListDetails object """
  89.         try:
  90.             data = urllib.urlencode(self.body)
  91.             request = urllib2.Request(
  92.                 self.baseurl + "start/", data, self.headers)
  93.             handle = self.opener.open(request)
  94.  
  95.             html_source = handle.read()
  96.            
  97.             if not re.findall(".*Add to Requests.*", html_source):
  98.                 print("The site has changed?")
  99.                
  100.             d = ListDetails()
  101.            
  102.             d.movies = re.search("<strong>Movies \(([0-9]{1,5})\)</strong>", html_source).group(1)
  103.             d.requests = re.search("<strong>Requests \(([0-9]{1,5})\)</strong>", html_source).group(1)
  104.            
  105.             # megabytes: movies / requests - array
  106.             array = re.findall("""<td width="103" height="15">([0-9]*)</td>""", html_source)
  107.             d.moviesmb = array[0]
  108.             d.requestsmb = array[1]
  109.        
  110.             # gigabytes: movies / requests - array
  111.             array =  re.findall("""<td height="15"> (.*,[0-9]{2}) </td>""", html_source)
  112.             d.moviesgb = array[0]
  113.             d.requestsgb = array[1]
  114.            
  115.             # CDs - array
  116.             array =  re.findall("""<td height="15"> ?([0-9]*) ?</td>""", html_source)
  117.             d.moviescds = array[0]
  118.             d.requestscds = array[1]
  119.            
  120.             d.messagespace = re.search("Message space used:([0-9]{1,3})%", html_source).group(1)
  121.  
  122.             return d          
  123.  
  124.         except (urllib2.URLError, urllib2.HTTPError), e:
  125.             if hasattr(e, 'code'):
  126.                 print 'We failed with error code - %s.' % e.code
  127.             elif hasattr(e, 'reason'):
  128.                 print "The error object has the following 'reason' attribute :", e.reason
  129.                 print "This usually means the server doesn't exist, is down, " + \
  130.                     "or we don't have an Internet connection."
  131.                    
  132.     def add_movie(self, movie):
  133.         """Adds a movie to your Origons movie list."""
  134.         if not isinstance(movie, Movie):
  135.             raise AttributeError()
  136.        
  137.         body = {
  138.                 "Title0": movie.title,
  139.                 "type0": movie.type,
  140.                 "Source0": movie.source,
  141.                 "cd0": movie.cds,
  142.                 "ResHeight0": movie.height,
  143.                 "ResWidth0": movie.width,
  144.                 "Size0": movie.size,
  145.                 "Releasedby0": movie.releasedby,
  146.                 "imdb0": movie.imdb,
  147.                 "Seen0": movie.seen,
  148.                 "Note0": movie.note,
  149.                 "Extra0": movie.extra,
  150.                 "lists": "1",
  151.                 "antal": "1",
  152.                 "status": "add",
  153.                 }
  154.         try:
  155.             data = urllib.urlencode(body)
  156.             request = urllib2.Request(
  157.                 self.baseurl + "movies/addm.asp?add=true", data, self.headers)
  158.             handle = self.opener.open(request)
  159.  
  160.             html_source = handle.read()
  161.            
  162.             if re.match(".*You have added the following movies.*", html_source):
  163.                 print("Adding movie successful: %s." % movie)
  164.          
  165.         except (urllib2.URLError, urllib2.HTTPError), e:
  166.             if hasattr(e, 'code'):
  167.                 print 'We failed with error code - %s.' % e.code
  168.             elif hasattr(e, 'reason'):
  169.                 print "The error object has the following 'reason' attribute :", e.reason
  170.                 print "This usually means the server doesn't exist, is down, " + \
  171.                     "or we don't have an Internet connection."
  172.                    
  173. class ListDetails(object):
  174.     """ Represents the statistics of the "Profile & Lists" page
  175.        of origons.com """
  176.     movies = ""
  177.     requests = ""
  178.     moviesmb = ""
  179.     requestsmb = ""
  180.     moviesgb = ""
  181.     requestsgb = ""
  182.     moviescds = ""
  183.     requestscds = ""
  184.     messagespace = ""
  185.    
  186.     def __str__(self):
  187.         result = "# movies: %s (%sGiB - %sCDs)\n" % \
  188.             (self.movies, self.moviesgb, self.moviescds)
  189.         result += "# requests: %s (%sGiB - %sCDs)\n" % \
  190.             (self.requests, self.requestsgb, self.requestscds)
  191.         result += "Message space used: %s%%" % self.messagespace
  192.         return result
  193.    
  194. class Movie(object):
  195.     """ Represents a movie that can be added to Origons. """
  196.     # [re.match(".*>(.*)</.*", line).group(1) for line in html.split()]
  197.     TYPE = ['3ivX', 'ASF', 'AVCHD', 'Blu-Ray', 'DAT', 'DivX', 'DVD', 'DVDR',
  198.             'HDDVD', 'iPod', 'M2V', 'MOV', 'MPEG', 'PSP', 'RAM', 'RV9',
  199.             'SMR', 'SVCD', 'VCD', 'VHS', 'WMV', 'X264', 'XVCD', 'XviD', '8mm',
  200.             '16mm', '']
  201.     SOURCE = ['CAM', 'Blu-Ray', 'DVD', 'HDDVD', 'HDTV', 'LDK', 'NTSC',
  202.               'PAL', 'SCR', 'TV', 'VHS', '']
  203.  
  204.     def get_title(self):
  205.         return self.__title
  206.     def get_type(self):
  207.         return self.__type
  208.     def get_source(self):
  209.         return self.__source
  210.     def get_cds(self):
  211.         return self.__cds
  212.     def get_height(self):
  213.         return self.__height
  214.     def get_width(self):
  215.         return self.__width
  216.     def get_size(self):
  217.         return self.__size
  218.     def get_releasedby(self):
  219.         return self.__releasedby
  220.     def get_imdb(self):
  221.         return self.__imdb
  222.     def get_seen(self):
  223.         return self.__seen
  224.     def get_note(self):
  225.         return self.__note
  226.     def get_extra(self):
  227.         return self.__extra
  228.    
  229.     def set_title(self, value): #Title0 100
  230.         if len(str(value)) > 100:
  231.             raise AttributeError()
  232.         self.__title = value
  233.     def set_type(self, value): #type0
  234.         value = [x for x in self.TYPE if x.lower() == value.strip().lower()]
  235.         if not value: # empty array: False
  236.             raise AttributeError()
  237.         self.__type = value[0] # get first element of array
  238.     def set_source(self, value): #Source0
  239.         value = [x for x in self.SOURCE if x.lower() == value.strip().lower()]
  240.         if not value:
  241.             raise AttributeError()
  242.         self.__source = value[0]
  243.     def set_cds(self, value): #cd0 3
  244.         value = filter(lambda x: x.isdigit(), value)
  245.         if (int(value) // 1000) > 0:
  246.             raise AttributeError()
  247.         self.__cds = value
  248.     def set_height(self, value): #ResHeight0 4
  249.         value = filter(lambda x: x.isdigit(), value)
  250.         if (int(value) // 10000) > 0:
  251.             raise AttributeError()
  252.         self.__height = value
  253.     def set_width(self, value): #ResWidth0 4
  254.         value = filter(lambda x: x.isdigit(), value)
  255.         if (int(value) // 10000) > 0:
  256.             raise AttributeError()
  257.         self.__width = value
  258.     def set_size(self, value): #Size0 10
  259.         # filter out additional characters like ',' and letters:
  260.         # >>> filter(lambda x: x.isdigit(), "qsdf1234,qsdf5d")
  261.         # '12345'
  262.         value = int(filter(lambda x: x.isdigit(), str(value)))
  263.         if (value // 10000000000) > 0:
  264.             raise AttributeError()
  265.         self.__size = value
  266.     def set_releasedby(self, value): #Releasedby0 20
  267.         if len(value) > 20:
  268.             raise AttributeError()
  269.         self.__releasedby = value
  270.     def set_imdb(self, value): #imdb0 7
  271.         """ Accepts whole IMDB URL. The string must contain 7 digits.
  272.            When bad input is given:
  273.            AttributeError: 'NoneType' object has no attribute 'group' """
  274.         self.__imdb = re.match("([0-7]{7})", value).group(1)
  275.     def set_seen(self, value): #Seen0 True/False
  276.         if value.lower() == "false":
  277.             value = False
  278.         self.__seen = bool(value) # True if not "false", False or 0
  279.     def set_note(self, value): #Note0 100
  280.         if len(value) > 100:
  281.             raise AttributeError()
  282.         self.__note = value
  283.     def set_extra(self, value): #Extra0 50
  284.         if len(value) > 50:
  285.             raise AttributeError()
  286.         self.__extra = value
  287.  
  288.     def del_title(self):
  289.         del self.__title
  290.     def del_type(self):
  291.         del self.__type
  292.     def del_source(self):
  293.         del self.__source
  294.     def del_cds(self):
  295.         del self.__cds
  296.     def del_height(self):
  297.         del self.__height
  298.     def del_width(self):
  299.         del self.__width
  300.     def del_size(self):
  301.         del self.__size
  302.     def del_releasedby(self):
  303.         del self.__releasedby
  304.     def del_imdb(self):
  305.         del self.__imdb
  306.     def del_seen(self):
  307.         del self.__seen
  308.     def del_note(self):
  309.         del self.__note
  310.     def del_extra(self):
  311.         del self.__extra
  312.                
  313.     __title = ""
  314.     __type = ""
  315.     __source = ""
  316.     __cds = ""
  317.     __height = ""
  318.     __width = ""
  319.     __size = ""
  320.     __releasedby = ""
  321.     __imdb = ""
  322.     __seen = False
  323.     __note = ""
  324.     __extra = ""
  325.  
  326.     title = property(get_title, set_title, del_title, "title's docstring")
  327.     type = property(get_type, set_type, del_type, "type's docstring")
  328.     source = property(get_source, set_source, del_source, "source's docstring")
  329.     cds = property(get_cds, set_cds, del_cds, "cds's docstring")
  330.     height = property(get_height, set_height, del_height, "height's docstring")
  331.     width = property(get_width, set_width, del_width, "width's docstring")
  332.     size = property(get_size, set_size, del_size, "size's docstring")
  333.     releasedby = property(get_releasedby, set_releasedby, del_releasedby, "releasedby's docstring")
  334.     imdb = property(get_imdb, set_imdb, del_imdb, "imdb's docstring")
  335.     seen = property(get_seen, set_seen, del_seen, "seen's docstring")
  336.     note = property(get_note, set_note, del_note, "note's docstring")
  337.     extra = property(get_extra, set_extra, del_extra, "extra's docstring")
  338.    
  339.     def __str__(self):
  340.         result = self.get_title()
  341.         if result == "":
  342.             result = "This movie has no title set. "
  343.         return result
  344.              
  345. if __name__ == '__main__':
  346.     movie = Movie()
  347.     movie.title = "Test (2011)"
  348.     movie.note = "hello world!"
  349.    
  350.     o = Origons3("username", "password")
  351.     o.list_details()
  352.     o.add_movie(movie)
RAW Paste Data