nattilypf: (Default)
Summary
=============================================
My project for this summer's Outreach Project for Women was to create a comprehensive moderator/administrator interface for Mediagoblin. This project centered on making it possible for any user to report an offensive piece of media or a comment and the ability to give different users different privileges which could be given or taken away (ie. moderator, commenter, admin). At this point I am essentially done! I have one quick change to make (making the User Panel capable of displaying more than 10 users), and I will be done! After that, I will be working closely with the #mediagoblin folks as they start to merge my changes to listen about if there will be any problems with migrations.

How my project went
=============================================
Working on this project went really really well! I often felt like I was *about* to be done months ahead of times, but there was always more to do :P The first work I did was making changes to the database such as the Privilege table and the Reports tables. Once I had all these set up, I set up the Foundations system, so that default Privileges were created whenever a new instance of Mediagoblin is instantiated. After all of the database stuff was done, I got to work on the views and templates. From this point on, I mostly did work creating new pages (like the moderator panels to monitor users and reports) and creating new code-tools. I made a decorator to check whether a user has the appropriate privileges or not before they visit a given page. The last couples months were primarily comprised of code testing and fine tuning.

I had a few minor snags which set me back a few weeks at a time. One big problem was SQLite3's inability to use Alter table commands, which makes it impossible for me to effectively remove the vestigial columns from the User table. I eventually had to just settle for marking them as vestigial and leaving them in the table. Aside from this, my work progressed fairly consistently.

How it works ( for devs )
=============================================
The foundational addition I made to the database was the creation of Privileges. A Privilege is a simple object that consists only of its name, its ID and a list of all the Users which have this privilege. The privileges that are now standard to a Mediagoblin Instance are: admin, moderator, uploader, commenter, reporter, active. Using the has_privilege decorator, a programmer can make any page require any privilege. Thus, it will be very easy to add new privileges should any become necessary. If a user does not have the proper privilege, they will be redirected to a 403 Forbidden page. I searched through the code and changed all references to the User columns is_admin, status and email_verified to instead reflect use the privileges 'admin' and 'active'. The User object has a method has_privilege which will tell whether the user has a certain privilege or not.

The other big changes I made were that I created Reports. I made three new tables for this purpose, ReportBase, MediaReports and CommentReports. Whenever a user reports a comment, a CommentReport is created and whenever a user reports a media entry, a MediaReport is created. A report can be resolved or open. When a User files a report it is open, and once a moderator responds to the report, they change the status to resolved. Moderators can resolve reports through any/all of the following actions:

  • Take away any/all privileges from the offending user

  • Delete the comment/media

  • Send an email to the offending user

  • Ban the user until a specified date

or the moderator can choose to take no punishment. The moderator needs to write an explanation of why they chose to resolve the report this way. The report is marked as resolved if the column 'resolved' is not None (the resolved column is a da "tetime which references when the comment was 'resolved'). This is generally the only way that a moderator can exercise their power. This way, any actions that a moderator takes are catalogued.



A picture of a internet browser visiting the page 127.0.0.1:6543. The text in the top left reads: Mediagoblin. On screen is a black background with a confused purple Goblin looking at a stack of papers. Next to the goblin is the text: You have been banned until 09-25-2013. You said some biggoted things and were making the website unsafe for other users. Think about what you have done



In order to ban a user, a UserBan object is created which has a foreign key relationship with the User. The UserBan object also holds information about why the user was banned, and at what point the ban will be lifted. If the expiration_date column is None, the user will be banned indefinitely. When the user tries to log into their banned account, any page they visit will be redirected to the You Are Banned page. This is managed through the user_not_banned decorator, which is also implied by the require_active_login decorator, which is implied by the user_has_privilege decorator




-------------------------------
How Foundations Work
-------------------------------
Foundations are a new way to create default objects that should be created with certain information at the initialization of a new mediagoblin instance. For migrations, users would just manually create new objects using the class constructors.
When a new instance is created, mediagoblin checks mediagoblin.db.models and every models.py file from every plugin for the FOUNDATIONS dictionary. The keys in the FOUNDATIONS dictionary are the class constructors of the table which will be initialized. The values of this dictionary need to be a list of dictionaries. Each of these minor dictionaries contain all of the necessary keyword arguments to create a new object when passed to the class constructor. So FOUNDATIONS[Privilege] points to a list of dictionaries containing {u'privilege_name':'whatever your privilege is called'}, because privilege_name is the only column necessary to instantiate a Privilege object.

-------------------------------
How to add a new Privilege
-------------------------------
To do this would just require a few steps.

1) You would have to add the privilege information to the FOUNDATIONS dictionary in mediagoblin.db.models.
2) Create a migration that brings the privilege into existence for already initialized instances.
3) Use the has_privilege decorator with your new privilege's name as the aruement for the pages you want to protect!
and you're done!
Summary
=============================================
My project for this summer's Outreach Project for Women was to create a comprehensive moderator/administrator interface for Mediagoblin. This project centered on making it possible for any user to report an offensive piece of media or a comment and the ability to give different users different privileges which could be given or taken away (ie. moderator, commenter, admin). At this point I am essentially done! I have one quick change to make (making the User Panel capable of displaying more than 10 users), and I will be done! After that, I will be working closely with the #mediagoblin folks as they start to merge my changes to listen about if there will be any problems with migrations.

How my project went
=============================================
Working on this project went really really well! I often felt like I was *about* to be done months ahead of times, but there was always more to do :P The first work I did was making changes to the database such as the Privilege table and the Reports tables. Once I had all these set up, I set up the Foundations system, so that default Privileges were created whenever a new instance of Mediagoblin is instantiated. After all of the database stuff was done, I got to work on the views and templates. From this point on, I mostly did work creating new pages (like the moderator panels to monitor users and reports) and creating new code-tools. I made a decorator to check whether a user has the appropriate privileges or not before they visit a given page. The last couples months were primarily comprised of code testing and fine tuning.

I had a few minor snags which set me back a few weeks at a time. One big problem was SQLite3's inability to use Alter table commands, which makes it impossible for me to effectively remove the vestigial columns from the User table. I eventually had to just settle for marking them as vestigial and leaving them in the table. Aside from this, my work progressed fairly consistently.

How it works ( for devs )
=============================================
The foundational addition I made to the database was the creation of Privileges. A Privilege is a simple object that consists only of its name, its ID and a list of all the Users which have this privilege. The privileges that are now standard to a Mediagoblin Instance are: admin, moderator, uploader, commenter, reporter, active. Using the has_privilege decorator, a programmer can make any page require any privilege. Thus, it will be very easy to add new privileges should any become necessary. If a user does not have the proper privilege, they will be redirected to a 403 Forbidden page. I searched through the code and changed all references to the User columns is_admin, status and email_verified to instead reflect use the privileges 'admin' and 'active'. The User object has a method has_privilege which will tell whether the user has a certain privilege or not.

The other big changes I made were that I created Reports. I made three new tables for this purpose, ReportBase, MediaReports and CommentReports. Whenever a user reports a comment, a CommentReport is created and whenever a user reports a media entry, a MediaReport is created. A report can be resolved or open. When a User files a report it is open, and once a moderator responds to the report, they change the status to resolved. Moderators can resolve reports through any/all of the following actions:
Take away any/all privileges from the offending user
Delete the comment/media
Send an email to the offending user
Ban the user until a specified date
or the moderator can choose to take no punishment. The moderator needs to write an explanation of why they chose to resolve the report this way. The report is marked as resolved if the column 'resolved' is not None (the resolved column is a datetime which references when the comment was 'resolved'). This is generally the only way that a moderator can exercise their power. This way, any actions that a moderator takes are catalogued.

A picture of a internet browser visiting the page 127.0.0.1:6543. The text in the top left reads: Mediagoblin. On screen is a black background with a confused purple Goblin looking at a stack of papers. Next to the goblin is the text: You have been banned until 09-25-2013. You said some biggoted things and were making the website unsafe for other users. Think about what you've done or be banned for good.

In order to ban a user, a UserBan object is created which has a foreign key relationship with the User. The UserBan object also holds information about why the user was banned, and at what point the ban will be lifted. If the expiration_date column is None, the user will be banned indefinitely. When the user tries to log into their banned account, any page they visit will be redirected to the You Are Banned page. This is managed through the user_not_banned decorator, which is also implied by the require_active_login decorator, which is implied by the user_has_privilege decorator

[decorator pic]


-------------------------------
How Foundations Work
-------------------------------
Foundations are a new way to create default objects that should be created with certain information at the initialization of a new mediagoblin instance. For migrations, users would just manually create new objects using the class constructors.
When a new instance is created, mediagoblin checks mediagoblin.db.models and every models.py file from every plugin for the FOUNDATIONS dictionary. The keys in the FOUNDATIONS dictionary are the class constructors of the table which will be initialized. The values of this dictionary need to be a list of dictionaries. Each of these minor dictionaries contain all of the necessary keyword arguments to create a new object when passed to the class constructor. So FOUNDATIONS[Privilege] points to a list of dictionaries containing {u'privilege_name':'whatever your privilege is called'}, because privilege_name is the only column necessary to instantiate a Privilege object.

-------------------------------
How to add a new Privilege
-------------------------------
To do this would just require a few steps.

1) You would have to add the privilege information to the FOUNDATIONS dictionary in mediagoblin.db.models.
2) Create a migration that brings the privilege into existence for already initialized instances.
3) Use the has_privilege decorator with your new privilege's name as the aruement for the pages you want to protect!
and you're done!
nattilypf: (Default)
Hi all,
So I've spent this last month making fine-detail adjustments to the code. I made a more clear way of get-ing whether or not a user has a given privilege. I added buttons to make the UI more usuable. I made it so that moderators are unable to punish moderators. And I started work on the Terms Of Service page. Now, I'm moving onto the actual final stages. Now, I really have a few minor tasks to do with the actual code and then I just need to write the unittests and pass my code onto someone else. I'm so excited to see this code in action :3

I'll let you know how the unittests go
- tilly-Q
nattilypf: (Default)
Okay! the mid term evaluation is coming up and I'm feeling really good about the work I've done. I'm just about at the point where I've finished the functionality of the moderation system! Now, users can file reports on objectionable content, and moderators can take disciplinary action to resolve the reports. The reports are all archived upon resolution. Admins, on the other hand, have the power to discipline users at will. The system of granting users privileges works and is expandable. In the process, I solved ticket 679 from http://issues.mediagoblin.org/ticket/679

Looking forward, I'm excited to have the time to make sure my code is as clean as possible. I'm hoping to update a few of the code snippets that my new systems make obsolete. For example, the User table used to have a Boolean column 'is_admin'. This is now obsolete because admins must be have the 'admin' privilege in their list of 'all_privileges'.

Aside from cleaning up my code, I'm also going to spend the rest of this time tweaking the UI with the input of other users. I also need to write most of my unittests.

But in short, I'm very excited to be on track. I'll be posting updates on some of my recent commits soon :]
nattilypf: (Default)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
July 8
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

This update I mostly did work on the templates for the admin pages. I did a co-
-uple other small changes. I changed the information around the media processi-
ng panel to be more specific, since it was written when it was the only admin
page. Git didn't catch this, but I renamed the templates, so mediagoblin/templ-
ates/admin/user.html now referrs to the page which shows the details of a spec-
ific user. The list view pages are now named ELEMENT_panel.html(ie. user_panel)
I also added a column reported_user_id to the ReportBase table, and had to add
to Report filing to make sure that column gets created. Also I moved the report
media button (on a media page) to the sidebar, though it still needs some form-
atting

--\ mediagoblin/static/images/icon_clipboard.png
--| Added this image for use in template mediagoblin/admin/report.html.
--| Distributed by the GNOME project http://www.gnome.org
--| Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
--| I'm still trying to figure out the appropriate way to attribute this in
   | the code

--\ mediagoblin/templates/mediagoblin/admin/media_panel.html
--| This template is actually the template formerly know as media.html. I
   | renamed it for clarity

--\ mediagoblin/templates/mediagoblin/admin/report_panel.html
--| This template is actually the template formerly know as report.html. I
   | renamed it for clarity

--\ mediagoblin/templates/mediagoblin/admin/user_panel.html
--| This template is actually the template formerly know as user.html. I renam-
   | -ed it for clarity

--\ mediagoblin/templates/mediagoblin/utils/report.html
--| This template is included in the media_home page. It is the report media
   | button. I figured I'd write it like this in case it got more complicated.

--\ mediagoblin/admin/routing.py
--| I changed the routing path /a/panel to /a/media for specificity

--\ mediagoblin/admin/views.py
--| I renamed admin_processing_panel to admin_media_processing_panel
--| I wrote a new view function admin_reports_detail
--| I wrote a new view function admin_users_detail

--\ mediagoblin/db/migrations.py
--| I added in the column reported_user_id to the ReportBase_v0 class

--\ mediagoblin/db/models.py
--| I added in the column reported_user_id to the ReportBase class

--\ mediagoblin/static/css/base.css
--| I added in css classes to display a report. Right now, they are just echo-
   | -ing the ways comments are displayed, but with the link in another color

--\ mediagoblin/templates/mediagoblin/admin/report.html
--| Created this new template (although git doesn't realize it) to show the de-
   | -tails of a specific report, indicated in the URL

--\ mediagoblin/templates/mediagoblin/admin/user.html
--| Created this new template (although git doesn't realize it) to show the de-
   | -tails of a specific user, indicated in the URL

--\ mediagoblin/templates/mediagoblin/base.html
--| Redirected the link from /a/panel to /a/media

--\ mediagoblin/templates/mediagoblin/user_pages/media.html
--| Moved the media report button to the sidebar

--\ mediagoblin/user_pages/lib.py
--| Changed the creation of reports, so that they also assign a column for rep-
   | -orted_user_id.
nattilypf: (Default)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
July 3
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

This was a simple commit. I changed all references to Groups into Privileges so
as to not conflict with the new federated groups which are also being written.
I also fixed up some of the code in the user_in_group/user_has_privilege decor-
ator. Users are now assigned the default privileges when they sign up, and ass-
iged active once they are activated. I updated the gmg command makeadmin to use
my groups as well. Lastly, I added the decorator to various views, requiring th-
at users belong to appropriate groups to access pages.

--\ mediagoblin/auth/tools.py
--| Added code to assign new users to default privileges

--\ mediagoblin/auth/views.py
--| Added code to assign users to u'active' privilege once the email
   | verification is complete

--\ mediagoblin/db/migrations.py
--| Renamed Group class to Privilege class

--\ mediagoblin/db/models.py
--| Renamed Group class to Privilege class

--\ mediagoblin/decorators.py
--| Renamed function based on the Group->Privilege change
--| Rewrote the function to be, ya know, functional

--\ mediagoblin/gmg_commands/users.py
--| Changed the 'makeadmin' command to add the target user to the admin
   | privilege group as well as affecting 'is_admin' column

--\ mediagoblin/submit/views.py
--| Added the requirement that a user has the 'uploader' privilege in order
   | to submit new media.

--\ mediagoblin/user_pages/views.py
--| Added the requirement that a user has the 'commenter' privilege in order
   | to make a comment.
--| Added the requirement that a user has the 'reporter' privilege in order
   | to submit new reports.
--| Got rid of some vestigial code in the file_a_report function.
nattilypf: (Default)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
June 27
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


In this commit, I have made a few changes and tightened up some of my models
code. I added in two major pieces of functionality: table foundations and a
decorator to confirm whether or not a user is a member of a certain group.

Table Foundations are default rows that should be present in a given table as
soon as the database is initialized. For example, I am using these to populate
the core__groups table with all of the necessary groups ('moderator', 'com-
menter', etc). Right now, this is achieved by adding a dictionary of parameters
(with the parameters as lists) to the constant FOUNDATIONS in
mediagoblin.db.models. The keys to this dictionary are uninstantiated classes.
The classes which require foundations also have must have a constructor so that
the list of parameters can be passed appropriately like so:
Model(*parameters)
In order to implement these foundations, I added the method populate_table_fou-
-ndations to MigrationManager in mediagoblin.db.migration_tools.

The decorator, called user_in_group, accepts as a parameter a unicode string,
and then decides whether to redirect to 403 or let the user access the page. The
identifier is the Group.group_name string, because I believe that will allow for
the most readable code.

I also added in the simple decorator require_admin_login.

In terms of tightening up my code, I made many minor changes to my use of white
space and made a few small documentation additions. I removed a vestigial class
(ReportForm) from mediagoblin.user_pages.forms. I moved all of my migrations in-
to one registered Migration.

Setting up Foundations
==============================

--\ mediagoblin/db/migration_tools.py
--| created: MigrationManager.populate_table_foundations
--| modified: MigrationManager.init_or_migrate to run
  | self.populate_table_foundations on init

--\ mediagoblin/db/models.py
--| created: FOUNDATIONS
----| created: group_foundations

Working With Permissions
==============================
--\ mediagoblin/decorators.py
--| created: user_in_group
--| created: require_admin_login

--\ mediagoblin/user_pages/views.py
--| modified: added decorator user_in_group to file_a_report

--\ mediagoblin/admin/views.py
--| modified: added decorator require_admin_login to all views functions

General Code Tidying
=============================

--/ mediagoblin/admin/views.py
--/ mediagoblin/user_pages/forms.py
--/ mediagoblin/db/models.py
--/ mediagoblin/user_pages/lib.py
--/ mediagoblin/user_pages/views.py
--/ mediagoblin/db/migrations.py
nattilypf: (Default)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
June 25
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

This is the first stage of my project of implenting admin/moderator functiona-
lity. At this point, I have finished all the of basic work with the models! I
still need to do some tightening of their documentation, but they seem to be
working well.

Working with Models
========================================

--\ mediagoblin/db/models.py
--| Added in the Report model and table. This model is strictly a parent
----| Added in the CommentReport model which holds information about a report
    | filed against a comment. This class inherits from Report.
----| Added in the MediaReport model which holds information about a report f-
    | -iled against a media entry. This class inherits from Report.
--| Added in a UserBan model and table. This model is in a one to one relatio-
  | -nship with User. This object acts as a marker for whether a user is banned
  | or not.
--| Added in a Group model. These objects are in a many-to-many relationship
  | with User to explain which privileges a User has.
----| Added in GroupUserAssociation which is a table used to hold this many to
    | many relationship between Group & User.

--\ mediagoblin/db/migrations.py
--| Added in the migrations for all of the additions to models
--| Added UserBan_v0
--| Added Report_v0
----| Added CommentReport_v0
----| Added MediaReport_v0
--| Added Group_v0
----| Added GroupUserAssociation_v0

Working with Templates, Views, and Routing
===============================================

>>> Reporting a Comment or a MediaEntry

--\ mediagoblin/user_pages/views.py
--| Added in the function file_a_report to allow user to file reports against
  | MediaEntries or Comments. Handles GET and POST requests.
--| Added in the function file_a_comment_report which uses file_a_report but
  | also catches appropriate information for comment_ids. I may be able to do
  | this more eloquently with decorators.

--\ mediagoblin/user_pages/routing.py
--| Added in route 'mediagoblin.user_pages.media_home.report_media'
  | (linked to address /u/[Unknown site tag]/m//report/ )
--| Added in route ''mediagoblin.user_pages.media_home.report_comment'
  | (linked to address /u/[Unknown site tag]/m//c//report/ )

--\ mediagoblin/templates/mediagoblin/user_pages/report.html
--| I created this file to handle the filing of a report.

--\ mediagoblin/templates/mediagoblin/user_pages/media.html
--| Modified this file to add in links allowing users to report either media
  | or comments.

--\ mediagoblin/user_pages/lib.py
--| Added in build_report_form which processes data as either a CommentReport or
  | a MediaReport depending on which parameters are present

--\ mediagoblin/user_pages/forms.py
--| Added in CommentReportForm
--| Added in MediaReportForm
--| note: ReportForm is vestigial to an earlier strategy I used and I'll remove it
  | promptly

--\ mediagoblin/decorators.py
--| Added in 'get_media_comment_by_id' for use in mediagoblin/user_pages/views.py

>>> New Admin Panels

--\ mediagoblin/admin/views.py
--| Added in the function admin_users_panel
--| Added in the function admin_reports_panel

--\ mediagoblin/admin/routing.py
--| Added in route 'mediagoblin.admin.users'
  | (linked to address '/a/users')
--| Added in route 'mediagoblin.admin.reports'
  | (linked to address '/a/reports/')

--\ mediagoblin/templates/admin/user.html
--| Created this file as a template for monitoring users

--\ mediagoblin/templates/admin/report.html
--| Created this file as a template for monitoring reports filed against media or
  | comments
nattilypf: (Default)
Hi everyone!

I always knew I was too unreliable for consistent blogging :/ To be honest, I just got started coding and was too into writing the code to talk about writing the code. I'll try to do a really good job of catching you up to wear I'm at now, to make up for it.

So basically, in my last post, I gave you all my comprehensive plan for implementation, and once I had created that, I felt totally ready to begin coding, so I started the actual hacking phase a little earlier than the 17th.

At this point: I believe I have done all of the work on changing the database that I need to do.

I've added in these classes to mediagoblin.db.models:

  • ReportBase

    • CommentReport

    • MediaReport

  • Group

  • UserBan



The Report classes are to be used whenever a user reports either a comment or a media entry. They hold information about the situation such as the offending entry's ID, the reason why it was reported, the reporting user's ID, etc.

The UserBan class is a simple one, it acts as like a marker to see if a user is currently banned. It exists in a one-to-one relationship with the User class, and if a User has a UserBan in relationship with them, they (the User) are currently banned. The UserBan table also has a column to hold the reason why the User was banned (to be displayed to the User if they try to log in) and a column that holds when the ban expires.

The Group class is in a many-to-many relationship with User. This one was a huge struggle for me to figure out how to fit with migrations, but at the end of a long night I got it \o/. That said.... I am currently using an association table that looks like this:
association_table = Table('core__group_user_associations', Base.metadata,
Column('core__group_id', Integer, ForeignKey(User.id)),
Column('core__user_id', Integer, ForeignKey(Group.id))
)

As you may have noticed... I did not refactor this into a class, so it 'core__group_user_associations' won't be instantiated when someone makes a new GMG instance. I will work on fixing this today *going back to the drawing board*

And, aside from all this work on models (obviously the *foundation* work), I've been making the skeleton pages of new admin pages. I've now set up an admin page to view/search for Users, and the view/search for Reports, but they both need a lot of work.

I've been visitting my family this week, so I will admit that in all the bustle of packing, this project got deprioritized, but now I've settled back it and am prepared and able to set aside the necessary hours~ I'll let you know how the home stretch of foundational models work goes!

tillyQ
nattilypf: (Default)
This just in: I LOVE organization

Implementation

  • Working with models
    • Create new Report Model
      • coderoute: mediagoblin.db.models.Report

        id = Column(Integer, primary_key=True)
        reporter_id = Column(Integer, ForeignKey('user.id')) #NOT SURE THIS IS CORRECT
        reporter =  Relationship(User, backref="reports_filed_by")
        offender_id = Column(Integer, ForeignKey('user.id')) #NOT SURE THIS IS CORRECT
        offender =  Relationship(User, backref="reports_filed_on")



        Subclass: MediaReport Model

        • coderoute: mediagoblin.db.models.MediaReport

          media_id = Column(Integer, ForeignKey('core_media_entries.id')) #NOT SURE THIS IS CORRECT
          media =  Relationship(MediaEntry, backref="reports_filed_on")

        Subclass: CommentReport Model

        • coderoute: mediagoblin.db.models.CommentReport

          media_id = Column(Integer, ForeignKey('core_media_comments.id')) #NOT SURE THIS IS CORRECT
          media =  Relationship(MediaComment, backref="reports_filed_on")

    • Create new Group Model
      • coderoute: mediagoblin.db.models.Group
      • Fields
        • id = Column(Integer, primary_key=True)
        • name = Column(Unicode, nullable=False, unique=True)
      • Initialize Default Groups
        • Default Groups
          • admin
          • moderator
          • active
            • is their email activated?
          • media-poster
          • commenter
          • banned
        • How-To?
    • Modify User Model
      • Add in a Many-to-Many Relationship Between User and Group
        • coderoute: mediagoblin.db.models.User

          docs: http://docs.sqlalchemy.org/en/rel_0_7/orm/relationships.html?highlight=many%20many

          advice: http://issues.mediagoblin.org/ticket/678

          groups = Relationship(Group,
          secondary=association_table,
          backref=backref("all_users",
              lazy="dynamic",
              cascade="all, delete-orphan"
          )     
          )





    • Create Association Table btwn User & Group
      • coderoute: mediagoblin.db.models
    • Migrations
      • coderoute: mediagoblin.db.migrations

        Task: Migrate old Users into User model w/ new Group relationship field and Group Id Field

        @RegisterMigration(11, MIGRATIONS)
        def add_group_id_column(db_conn):
            metadata = MetaData(bind=db_conn.bind)

             users = Table('core__users', metadata, autoload=True,
                   autoload_with=db_conn.bind)

             col =  XXXXXXXXXXXXXXXXFILL THIS INXXXXXXXXXXXXX
            col.create(users, populate_defaults=True)

            db_conn.commit()









  • Working with web pages
    • Modify Old Pages
      • Admin Pages {/a/}
        • Media Processing Panel
          • Task: Rename the functions and urlroutes away from the general word 'panel'
          • routing
            • coderoute: mediagoblin.admin.routing

              REPLACE

                  ('mediagoblin.admin.panel',

                      '/panel',

                      'mediagoblin.admin.views:admin_processing_panel'),

              WITH

                  ('mediagoblin.admin.media_processsing',

                      '/media',

                      'mediagoblin.admin.views:admin_media_processing_panel'),

          • views
            • coderoute: mediagoblin.admin.views

              REPLACE

                  def admin_processing_panel:

              WITH

                  def admin_media_processing_panel:

              REPLACE

                  return render_to_response(

                      request,

                      'mediagoblin/admin/panel.html',

              WITH

                  return render_to_response(

                      request,

                      'mediagoblin/admin/media_panel.html',

          • template
            • coderoute: templates.mediagoblin.admin.panel.html
            • $ mv panel.html media_pane.html
      • User Pages {/u/}
        • Media Home Page
          • coderoute: templates.mediagoblin.user_pages.media.html
          • Add in a report button for all users
            • coderoute: templates.mediagoblin.user_pages.media.html
          • Add in moderator/admin only visible actions
            • coderoute: templates.mediagoblin.user_pages.media.html
        • User Home Page
          • coderoute: templates.mediagoblin.user_pages.user.html
          • Add in a report button for all users
            • coderoute: templates.mediagoblin.user_pages.user.html
          • Add in moderator/admin only visible actions
            • coderoute: templates.mediagoblin.user_pages.user.html
    • Add new Pages
      • Admin Pages {/a/}
        • coderoute: mediagoblin.admin
        • templateroute: mediagoblin.admin
        • User Management Panel
          • routing.py
            • coderoute: mediagoblin.admin.routing
            •    ('mediagoblin.admin.users',
              '/users',
              'mediagoblin.admin.views:admin_users_panel')

          • views.py
            • coderoute: mediagoblin.admin.views:admin_users_panel
          • template
        • Reports Processing Panel
          • routing.py
            • coderoute: mediagoblin.admin.routing
            •    ('mediagoblin.admin.reports',
              '/reports',
              'mediagoblin.admin.views:admin_reports_panel')

          • views.py
            • coderoute: mediagoblin.admin.views:admin_reports_panel
          • template
        • Groups Panel
          • routing.py
            • coderoute: mediagoblin.admin.routing
            •    ('mediagoblin.admin.groups',
              '/groups',
              'mediagoblin.admin.views:admin_groups_panel')

          • views.py
            • coderoute: mediagoblin.admin.views:admin_groups_panel
          • template
        • Editting the Code of Conduct
          • routing.py
            • coderoute: mediagoblin.admin.routing

                 ('mediagoblin.admin.code_of_conduct',
              '/code-of-conduct',
              'mediagoblin.admin.views:admin_code_of_conduct_panel')

          • views.py
            • coderoute: mediagoblin.admin.views:admin_code_of_conduct_panel
          • template
      • Moderator Pages
        • coderoute: mediagoblin.moderator

          templateroute: mediagoblin.moderator

          $ mkdir mediagoblin/moderator \

              mediagoblin/templates/mediagoblin/moderator

          User Management Panel

          • routing.py
            • coderoute: mediagoblin.moderator.routing

                 ('mediagoblin.moderator.users',
              '/users',
              'mediagoblin.moderator.views:moderator_users_panel')

          • views.py
            • coderoute: mediagoblin.moderator.views:moderator_users_panel
          • template

          Reports Processing Panel

          • routing.py
            • coderoute: mediagoblin.moderator.routing

                 ('mediagoblin.moderator.reports',
              '/reports',
              'mediagoblin.moderator.views:moderator_reports_panel')

          • views.py
            • coderoute: mediagoblin.moderator.views:moderator_reports_panel
          • template

      • Everyone Pages
        • Code of Conduct
          • routing.py
            • coderoute: mediagoblin.routing
          • views.py
          • template
        • Reports Observation Page
          • routing.py
            • coderoute: mediagoblin.routing
          • views.py
          • template
        • Website Punishment History page
          • routing.py
            • coderoute: mediagoblin.routing
          • views.py
          • template
        • Personal Punishment History Page
          • routing.py
            • coderoute: mediagoblin.user_pages.routing

              add_route('mediagoblin.user_pages.punishment_history',
              '/u/<string:user>/punishment-history',
              'mediagoblin.user_pages.views:user_punishment_history')

          • views.py
          • template
        • Report POST Request page
          • coderoute mediagoblin.???
          • Purpose: Creates a Report
          • routing.py
          • views.py
          • template
          • data
            • Offending comment_id/media_id
            • Offender user_id
            • Reporter user_id
            • Referring URL
      • Punished User Pages
        • Why are you banned? Page
      • <Process of Adding Pages>
        • Add new templates to Templates Foler
        • Add new entry to appropriate Routing.py
        • Add new entry to appropriate Views.py
    • Include New Pages
      • Add to mediagoblin.routing

        • from mediagoblin.moderator.routing import moderator_routes

          ...

              mount('mod', moderator_routes)

  • Working with other aspects
    • Create new Method to Check User's Group Status
      • coderoute: mediagbolin.tools.???
      • advice: http://issues.mediagoblin.org/ticket/678
    • Create new Form Objects
      • Create new ReportForm
        • coderoute: mediagoblin.user_pages.forms
      • GroupCreateForm
      • AttachUserToGroup
nattilypf: (Default)
~ R e s e a r c h   T o - D o   L i s t ~
☑ Read up on Django
☑ Learn about basics and query selection in SQLAlchemy
☑ Learn about many-to-many relationships in SQLAlchemy
☐ Research a few admin/moderation styles
☑ Familiarize myself with various facets of the mediagoblin package
☐ Learn about comment submission process
☑ Learn about User model type in mediagoblin.db.models
☐ Learn about media submission process
☑ Read about writing mediagoblin plug-ins
☑ Research database migrations


~ P l a n n i n g   T o - D o L i s t ~

☑ Figure out which packages I need to research
☑ Decide how many and what type of pages will be needed
☐ Making general logistical and implementation decisions
☐ Which permission states there should be?
☒ Make it a scale, so that permission checks can be done with >=?
☒ Make it based on multiples so that permission checks can be done with %?
☑ Permissions will be handled thru the use of a new Group model
☐ Whether to include moderators or not?
☐ Should users have moderation over their own pages?


~ I m p l e m e n t a t i o n   T o - D o L i s t ~

☐ Add new urls to mediagoblin.admin.routing
☐ Add new views to mediagoblin.admin.views
☐ Add new templates to mediagoblin.templates.admin
☐ Rename the media processing panel appropriately
☐ Rename url route for '/a/panel' mediagoblin.admin.routing
☐ Rename admin_processing_panel function in mediagoblin.admin.views
☑ Modify the user model to include permissions
☒ Add a new Column(Integer) variable to the User model in mediagoblin.db.models
☑ Add a new Group class to models
☑ Build a many-to-many relationship btwn User(s) and Group(s)
☐ Modify various pages to allow/reject the user to take an action based on their permissions
☐ Prevent punished users from posting comments
☐ Prevent punished users from posting media
☑ Modify various templates to add in a clickable Report button
☐ Modify various templates to add in links only visible to admins or moderators
☐ Add new urls to various files of routing.py to account for Report POST/GET requests
☐ Write documentation for docs.mediagoblin.org about proper use of administration
☐ Write a draft and share it with other mediagoblin devs


Just finished : ☑ Research database migrations
Currently working on : ☐ Learn about many-to-many relationships in SQLAlchemy

------------------------------------------
(symbols for reference)
☐ This is a task to do!
☑ This is a task that you've done, good job!
☒ You decided that this task was not actually worth doing/possible to do, that's fine!
------------------------------------------
nattilypf: (Default)
First, I realized that I haven't really gone into what my project is yet. Luckily~ I wrote a summary of that already, basically my project is:

Creating pages on a mediagoblin server to act as user interfaces for administrators and/or moderators. Giving administrators the power to remove media, users or comments and to enact other punitive measures.

It feels to me like an important topic, and I am excited to dip into the many nuances and questions of it.

I've been spending these last days diving back into my application and trying to figure out exactly what I need to learn and what I decisions I need to make to be able to go forward. I went thru the Django tutorial and now the layout of Mediagoblin makes perfect sense to me :D

I still have a few key decisions to make here. I've got lots of ideas about how make this happen and with all of them, it can be kind of overwhelming!! So I've been making things simpler by making a well-organized (and attractively laid out) plan, which you can find below. I'm planning to be constantly updating this list with my progress:

Project To-Do List

thanks for reading!
>>tilly-Q<
nattilypf: (Default)
I am so grateful and so excited to say that I have been accepted into the GNOME Outreach Project for Women! I'm going to be working on an Administrative/Moderation System for mediagoblin from June through September. I've written a proposal for how I imagine doing this, and I may post part of it up here shortly once I get to make it more concrete.

I can't wait to work with my awesome mentor and I've been spending today making sure that my development environment is set up just right. I also would love to meet some of the other folks who got accepted and will be logging onto the #opw IRC channel tonite [internet chat does make me anxious sometimes though, one step at a time ;)].

Anyway, thanks for reading, I'll be posting more updates soon~

>>>tilly-Q<

BTW can I just say: I think this is my first time writing in a blog... get with the times, I know XD. Excited about that too tho~~

September 2013

S M T W T F S
1234567
891011121314
1516171819 2021
22232425262728
2930     

Project To-Do List

~A summary of what I'm currently working on and what I still have yet to do~
Page generated Sep. 3rd, 2014 04:31 am
Powered by Dreamwidth Studios